windows UDP网络服务端编程 详解
引言:
- 在使用套接字进行编程之前,无论是服务器还是客户端都必须加载Windows SOCKET动态库。函数WSAStartup就实现了此功能。它是套接字应用程序必须调用的第一个函数。可以参考:http://blog.csdn.net/ithzhang/article/details/8448655
- Windows SOCKET可以支持多种不同的网络协议,并且提供与协议无关的编程接口。因此开发人员就可以相同的格式开发使用任一协议的网络应用程序,而不去关心各种协议的不同。
- 每种协议都有一套不同的IP定址方案(即表示主机地址的方式)。TCP协议和UDP协议通过IP协议传输数据。
- 关于socket编程的一些函数说明:http://patton.spaces.eepw.com.cn/articles/article/item/23229
一、语句解析
1、第一个片段: 创建套接字
SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);
SOCKET socket(int af, // [in] Address family specification.
int type, // [in] Type specification for the new socket
int protocol // [in] Protocol to be used with the socket that is specific to the indicated address family
);
- Windows sockets中定义的套接字类型SOCKET来表示套接字:
typedef unsigned int u_int; typedef u_int SOCKET; 其实所谓的SOCKET的类型只不过是unsigned int的别名罢了
- Windows SOCKET通过AF_INET地址家族为IP协议定址。
#define AF_INET 2
- 网络中每台主机都有一个IP地址,用32位数字来表示。TCP和UDP必须指定端口号。在Windows SOCKET中sockaddr_in 结构被用来指定IP和端口号。
- AF_INET: AF 表示ADDRESS FAMILY 地址族;PF 表示PROTOCOL FAMILY 协议族
2、第二个片段:为绑定地址做准备
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
- SOCKADDR_IN 相关的解析
typedef struct sockaddr_in SOCKADDR_IN; struct sockaddr_in{ short sin_family; // Address family (must be AF_INET). unsigned short sin_port; // IP port. struct in_addr sin_addr; // IP address. char sin_zero[8]; // Padding to make structure the same size as SOCKADDR. };
struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; };
- htonl的解析:将无符号长整型主机字节序转换为网络字节序。主机一般是低字节存储,而网络一般是高字节存储。
htonl The htonl function converts a u_long from host to TCP/IP network byte order (which is big-endian). u_long htonl( u_long hostlong );
- htons的解析:将无符号短整型主机字节序转换为网络字节序
htons The htons function converts a u_short from host to TCP/IP network byte order (which is big-endian). u_short htons( u_short hostshort );
相关介绍可查照:http://www.360doc.com/content/13/0624/19/12906934_295244758.shtml
3、第三个片段:将创建的套接字与本机地址相绑定。
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
The bind function associates a local address with a socket.
int bind( SOCKET s, // [in] Descriptor identifying an unbound socket. const struct sockaddr FAR *name, // [in] Address to assign to the socket from the SOCKADDR structure. int namelen // [in] Length of the value in the name parameter. );
4、第四个片段:为接收和发送信息做准备
char recvBuf[100];
char sendBuf[100];
char tempBuf[100];
SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);
5、相互通信,服务端首先得等待接收信息。
while (1)
{
recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
if ('q'==recvBuf[0])
{
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);
cout << "Char end!" << endl;
break;
}
sprintf(tempBuf,"%s say : %s",inet_ntoa(addrClient.sin_addr),recvBuf);
cout << tempBuf << endl;
cout << "please input data:" << endl;
gets(sendBuf);
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
}
- recvfrom解析:它接收数据报和存储数据报来源的地址。
recvfrom The recvfrom function receives a datagram and stores the source address. int recvfrom( SOCKET s, //[in] Descriptor identifying a bound socket. char FAR* buf, //[out] Buffer for the incoming data. int len, //[in] Length of buf. int flags, //[in] Indicator specifying the way in which the call is made. struct sockaddr FAR *from, //[out] Optional pointer to a buffer that will hold the source address upon return. int FAR *fromlen //[in, out] Optional pointer to the size of the from buffer. );
sendto解析:发送数据到指定的目的地
sendto The sendto function sends data to a specific destination. int sendto( SOCKET s, // [in] Descriptor identifying a (possibly connected) socket const char FAR *buf, // [in] Buffer containing the data to be transmitted int len, // [in] Length of the data in buf int flags, // [in] Indicator specifying the way in which the call is made const struct sockaddr FAR *to, // [in] Optional pointer to the address of the target socket int tolen // [in] Size of the address in to );
inet_ntoa解析:将网络地址转换成“.”点隔的字符串格式。详情可以参照:------>>>>点击。
inet_ntoa The inet_ntoa function converts an (Ipv4) Internet network address into a string in Internet standard dotted format. char FAR * inet_ntoa( struct in_addr in // [in] Structure that represents an Internet host address );
6、关闭套接字,及清理套接字库
closesocket(sockSrv);
WSACleanup();
- closesocket解析:关闭现存的套接字。
closesocket The closesocket function closes an existing socket. int closesocket( SOCKET s // [in] Descriptor identifying the socket to close );
WSACleanup解析:终止,做实际的清除工作。
WSACleanup The WSACleanup function terminates use of the Ws2_32.dll. int WSACleanup (void);