最开始怀疑使用sendto、recvfrom函数的最后一个参数的变量值没有初始化大小,即没有int addrlen = sizeof(SOCKADDR),使用之后问题依然存在;
网上看到下面的说法:
2.经过多次试验,排查到原因,是因为客户端使用大小为32的缓冲区char recvBuffer[32]进行接收,但主控发送时,发送的大小为sizeof(CLIENTDATA) = 65,导致客户端接收失败,返回-1,即使客户端套接字状态正常依然返回-1。当客户端接收缓冲区改为大于主控发送的数据的任意大小缓冲区,recvfrom不再返回-1。
3.所以,使用UDP进行数据传输时,接收端recvfrom时缓冲区的大小要大于发送端发送数据的大小,否则recvfrom返回SOCKET_ERROR,即-1。
代码:
int n = 0, i;
int len = sizeof(SOCKADDR);
/*printf("\nsendbuf:");
for (i = 0; i < length; i++) {
printf("%02x ", (u8)sendbuf[i]);
}
printf("\n\n");*/
n = sendto(udpfd, sendbuf, length, 0, (struct sockaddr*)&udpsockaddr, len);
if (n < 0) {
OutputDebugString("sendto error\n");
return 0;
}
memset(recvbuf, 0, 64);
n = recvfrom(udpfd, recvbuf, length, 0, (struct sockaddr*)&udpsockaddr, &len);
if (n < 0) {
OutputDebugString("recvfrom error\n");
}
同样,把recvfrom的第三个参数length=12修改为大于等于22后就再没有 recvfrom error 报错了。