C++ C++;UDP。为什么recvfrom()没有阻塞?
我正在使用UDP编写一些简单的客户机/服务器代码。程序运行良好,但如果我只启动客户端,recvfrom方法不会阻塞。但是,当我删除sendto方法时,recvfrom开始阻塞。知道发生了什么吗 以下是客户端代码:C++ C++;UDP。为什么recvfrom()没有阻塞?,c++,client,udp,winsock,blocking,C++,Client,Udp,Winsock,Blocking,我正在使用UDP编写一些简单的客户机/服务器代码。程序运行良好,但如果我只启动客户端,recvfrom方法不会阻塞。但是,当我删除sendto方法时,recvfrom开始阻塞。知道发生了什么吗 以下是客户端代码: int server_length; /* Length of server struct */ char send_buffer[256] = "hi"; /* Data to send */ ti
int server_length; /* Length of server struct */
char send_buffer[256] = "hi"; /* Data to send */
time_t current_time; /* Time received */
while(true)
{
/* Tranmsit data to get time */
server_length = sizeof(struct sockaddr_in);
if (sendto(m_oSocket, send_buffer, (int)strlen(send_buffer) + 1, 0, (struct sockaddr *)&m_oServer, server_length) == -1)
{
fprintf(stderr, "Error transmitting data.\n");
continue;
}
/* Receive time */
if (recvfrom(m_oSocket, (char *)¤t_time, (int)sizeof(current_time), 0, (struct sockaddr *)&m_oServer, &server_length) < 0)
{
fprintf(stderr, "Error receiving data.\n");
continue;
}
/* Display time */
printf("Current time: %s\n", ctime(¤t_time));
Sleep(1000);
}
看起来您正在以相同的方式设置服务器套接字和客户端套接字。对于服务器,初始化看起来不错,但是对于客户端,您需要绑定到端口0
事实上,对于这两个端口,您都可以执行INADR_ANY(IP 0.0.0.0),它不绑定到特定的接口,而是允许在正确的端口上进行任何连接。有多种方法可以使发送失败。一些,如arp故障,将在
sendto
期间导致错误。下次使用该套接字时,可能会报告其他问题,例如无法访问的ICMP端口
您的recvfrom
调用实际上可能正在获取为响应传出数据包而发送的ICMP数据包
第二个
recvfrom是否按预期阻塞?套接字需要设置为阻塞/非阻塞
集块
int nMode = 0; // 0: BLOCKING
if (ioctlsocket (objSocket, FIONBIO, &nMode) == SOCKET_ERROR)
{
closesocket(SendingSocket);
WSACleanup();
return iRet;
}
设置非阻塞
int nMode = 1; // 1: NON-BLOCKING
if (ioctlsocket (objSocket, FIONBIO, &nMode) == SOCKET_ERROR)
{
closesocket(SendingSocket);
WSACleanup();
return iRet;
}
你是如何设置插座的?您可以添加相关代码吗?可能是因为您正在向自己发送,所以“recvfrom()”总是有数据在等待它吗?请尝试绑定到0以外的端口。我正在同一台计算机上运行客户端和服务器。如果我同时运行客户端和服务器,并停止并重新启动客户端,它仍然能够连接。但是,当我停止服务器并重新启动它时,客户端不会重新连接。这可能与您没有使用SO\u REUSEADDR
选项有关。我不是插座专家,只是想给你一些线索。不,他们不是。阻塞模式是默认模式,这就是他所使用的。
int nMode = 1; // 1: NON-BLOCKING
if (ioctlsocket (objSocket, FIONBIO, &nMode) == SOCKET_ERROR)
{
closesocket(SendingSocket);
WSACleanup();
return iRet;
}