UDP通信的定义
Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。
Winsock用于通信的结构体
首先认识几个Windows提供的结构体:
WORD:为微软SDK中的类型,为两个Byte的无符号整数,可用MAKEWORD函数生成,语句为WORD Wrd = MAKEWORD(bLow,bHigh);
SOCKET: 用于创建socket,可作为数据的接收端或发出端
SOCKADDR_IN:该结构体指定了地址族(sin_family), 16位TCP/UDP端口号(sin_port),32位IP地址(sin_addr),与保留的字符数组char sin_zeros[8]
服务端socket建立
1.调用WSAStartup函数,启动Windows Sockets Asynchronous,即Windos异步嵌套字,完成Winsock服务初始化。
2.调用socket函数建立服务端socket,参数指明为UDP通信。
sServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3.将该socket与SOCKADDR_IN类型的数据变量通过bind函数绑定,该变量指定了socket的地址族、端口号与IP地址。
服务端程序源码
int socket_init()
{
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
printf("WSAStartup failed\n");
return -1;
}
sServer = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //采用UDP
if (sServer == INVALID_SOCKET) {
printf("socket establish failed\n");
return -1;
}
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(9990); //相同的端口响应相同端口的请求
addrServ.sin_addr.S_un.S_addr = htons(INADDR_ANY);
retVal = bind(sServer, (const sockaddr*)&addrServ, sizeof(SOCKADDR_IN));
if (retVal == SOCKET_ERROR) {
printf("bind failed\n");
closesocket(sServer);
WSACleanup();
return -1;
}
return 0;
}
用户端socket建立
1.同样调用WSAStartup函数,完成Winsock服务初始化。
2.调用socket函数建立服务端socket,参数指明为UDP通信。
sHost = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
3.指明与该socket(sHost)进行数据交换socket的地址,即需要定义一个SOCKADDR_IN类型的变量,指定服务端的地址族、端口号与IP地址
用户端程序源码
int socket_init() {
if (WSAStartup(wVersionRequested, &wsaData) != 0) {
printf("WSAStartup failed\n");
return -1;
}
sHost = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //UDP
if (sHost == INVALID_SOCKET) {
printf("socket establish failed\n");
WSACleanup();
return -1;
}
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(9990);
addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int sServerAddrLen = sizeof(addrServ);
return 0;
}
信息的接收与发送
在WinSock实现的UDP通信中,我们通过sendto与recvfrom函数实现信息的发送与接收。
int sendto ( socket s , const void * msg, int len, unsigned int flags, const
struct sockaddr * to , int tolen ) ;
在该函数中,s为信息发送端,msg为信息首地址,len为长度,flags一般设为0,to指定接收信息的socket地址信息,tolen为地址信息的长度。
int recvfrom(SOCKET s,void *buf,int len,unsigned int flags, struct sockaddr *from,int *fromlen);
recvfrom函数的参数与sendto基本相同,同样需要指明发送信息的socket,接受信息的socket地址信息。
UDP通信的特点
1.UDP通信是无连接的传输层协议,这通过其调用sendto与recvfrom函数时需要指定接收方就可以看出。
2.UDP尽最大努力传输数据,但不能保证可靠交付。
3.UDP传输相对较快,且支持一对一、一对多、多对多的交互通信.