C++ C++;UDP。为什么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

我正在使用UDP编写一些简单的客户机/服务器代码。程序运行良好,但如果我只启动客户端,recvfrom方法不会阻塞。但是,当我删除sendto方法时,recvfrom开始阻塞。知道发生了什么吗

以下是客户端代码:

    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 *)&current_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(&current_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;
     }