发送到 C 中关闭的 UDP 套接字不会引发错误

Sar*_*Sin 0 c sockets udp

我正在尝试“测试”UDP 套接字是否打开作为终止程序的一种方式:

 int flags = fcntl(s, F_GETFL, 0);
        fcntl(s, F_SETFL, flags | O_NONBLOCK);
        int x = recv(s, buffer, sizeof(buffer), 0);
        if (x == -1)
        {
            char temp[] = "Testing Connection";
            int x = sendto(s, temp, sizeof(temp), 0, (struct sockaddr *)&si_other, sizeof(si_other));
            printf("%d\n",x);
            if(x == -1){
                return;
            }
            continue;
        }
Run Code Online (Sandbox Code Playgroud)

但是 if 语句没有被触发。它正在发送数据的 UDP 套接字运行以下行(我知道它运行是因为 print 语句打印

    printf("Closing the socket\n");
    close(s);
    return;
Run Code Online (Sandbox Code Playgroud)

即使它尝试发送到的 udp 套接字已关闭,sendto 也会持续返回正值。有没有什么办法解决这一问题?

Chr*_*odd 7

由于 UDP 是数据报协议并且不是面向连接的,因此无法直接获取与连接相关的错误。您只需将数据包发送到互联网,它们可能会被某人收到或可能会丢失。

在某些系统(例如 Linux)上您可以执行的操作是在套接字上设置IP_RECVERR选项。如果这样做,则可以使用带有MSG_ERRQUEUE标志的recv(2)来查看系统是否已收到与您发送的数据包相关的任何 ICMP 错误消息。ip (7)手册页对此有描述。请注意,没有看到错误响应并不意味着该数据包已被等待它的人收到。在导致 icmp 错误之前,它可能已因各种原因被丢弃,或者接收计算机可能被配置为不生成错误(或者可能已完全消失),或者 icmp 错误本身可能在返回给您之前已丢失。

然而,最常见的是,您只需发送数据包并等待一段时间的响应,然后重新发送内容(如果在多次发送后没有得到响应,则会失败)。这就是 TCP“在幕后”所做的事情,等待 ACK 数据包,如果没有收到数据包,则重新发送数据(并最终切断连接)。