[英]C++ UDP. Why is recvfrom() is not blocking?
I am writing some simple client/server code using UDP. 我正在使用UDP编写一些简单的客户端/服务器代码。 The program works fine, but if I only start the client, the recvfrom method does not block.
该程序运行良好,但是如果我仅启动客户端,则recvfrom方法不会阻塞。 However, when I remove the sendto method, recvfrom starts to block.
但是,当我删除sendto方法时,recvfrom开始阻塞。 Any idea of what is going on?
有什么想法吗?
Here is the client side code: 这是客户端代码:
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);
}
And here is the initialization: 这是初始化:
unsigned short m_iPortnumber;
struct sockaddr_in m_oServer;
struct sockaddr_in m_oClient;
SOCKET m_oSocket;
WSADATA w; /* Used to open Windows connection */
int a1, a2, a3, a4; /* Server address components in xxx.xxx.xxx.xxx form */
a1 = 192;
a2 = 168;
a3 = 2;
a4 = 14;
m_iPortnumber = 52685;
/* Open windows connection */
if (WSAStartup(0x0101, &w) != 0)
{
fprintf(stderr, "Could not open Windows connection.\n");
exit(0);
}
/* Open a datagram socket */
m_oSocket = socket(AF_INET, SOCK_DGRAM, 0);
if (m_oSocket == INVALID_SOCKET)
{
fprintf(stderr, "Could not create socket.\n");
WSACleanup();
exit(0);
}
/* Clear out server struct */
memset((void *)&m_oServer, '\0', sizeof(struct sockaddr_in));
/* Set family and port */
m_oServer.sin_family = AF_INET;
m_oServer.sin_port = htons(m_iPortnumber);
/* Set server address */
m_oServer.sin_addr.S_un.S_un_b.s_b1 = (unsigned char)a1;
m_oServer.sin_addr.S_un.S_un_b.s_b2 = (unsigned char)a2;
m_oServer.sin_addr.S_un.S_un_b.s_b3 = (unsigned char)a3;
m_oServer.sin_addr.S_un.S_un_b.s_b4 = (unsigned char)a4;
/* Clear out client struct */
memset((void *)&m_oClient, '\0', sizeof(struct sockaddr_in));
/* Set family and port */
m_oClient.sin_family = AF_INET;
m_oClient.sin_addr.s_addr=INADDR_ANY;
m_oClient.sin_port = htons(0);
/* Bind local address to socket */
if (bind(m_oSocket, (struct sockaddr *)&m_oClient, sizeof(struct sockaddr_in)) == -1)
{
fprintf(stderr, "Cannot bind address to socket.\n");
closesocket(m_oSocket);
WSACleanup();
exit(0);
}
There are a variety of ways that sendto
can fail. sendto
可能有多种失败方式。 Some, such as arp failure, will cause an error during sendto
. 某些错误(例如arp故障)将在
sendto
期间导致错误。 Other, such as ICMP port unreachable
, may be reported when you next use the socket. 下次使用套接字时,可能会报告其他信息,例如
ICMP port unreachable
。
Your recvfrom
call could actually be fetching the ICMP packet sent in response to your outgoing packet. 您的
recvfrom
调用实际上可能是在获取响应您的传出数据包而发送的ICMP数据包。
Does a second recvfrom
block as expected? 第二个
recvfrom
是否按预期阻止了?
Socket required to be set BLOCKING/NON-BLOCKING. 套接字需要设置为“阻止/非阻止”。
Set BLOCKING 设定封锁
int nMode = 0; // 0: BLOCKING if (ioctlsocket (objSocket, FIONBIO, &nMode) == SOCKET_ERROR) { closesocket(SendingSocket); WSACleanup(); return iRet; }
Set NON-BLOCKING 设置为非阻塞
int nMode = 1; // 1: NON-BLOCKING if (ioctlsocket (objSocket, FIONBIO, &nMode) == SOCKET_ERROR) { closesocket(SendingSocket); WSACleanup(); return iRet; }
It looks like you're setting up the server socket and the client socket the same way. 看起来您正在以相同的方式设置服务器套接字和客户端套接字。 The initialization looks good for a server, but for the client, you'll want to bind to port 0.
初始化对于服务器来说看起来不错,但是对于客户端,您将需要绑定到端口0。
In fact, for both of them you can do INADDR_ANY (IP 0.0.0.0), which doesn't bind to a specific interface, but instead allows any connection on the correct port. 实际上,对于它们两者,您都可以执行INADDR_ANY(IP 0.0.0.0),它不绑定到特定的接口,而是允许在正确的端口上进行任何连接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.