在Linux下运行的C++程序中有一个UDP文件描述符。我在上面调用connect()将其连接到远程地址,然后从该套接字中读取和写入。
根据UNIX网络编程,“异步错误返回给连接的UDP套接字的进程。”我猜想这些异步错误将导致操作系统关闭UDP套接字,但这本书并不那么清楚。还不清楚哪些类型的异步错误是可能的,尽管建议如果远程计算机上的端口不打开,套接字将被关闭。
所以我的问题是:在什么情况下Linux将关闭UDP文件描述符?
发布于 2011-04-28 19:52:17
连接()在UDP套接字上只记录您传入的端口号和IP地址,因此它将只接受来自该IP/端口的数据包,并且您可以使用套接字fd发送/写入数据,而不指定每个发送/写入调用的远程地址。
关于这一点,异步错误意味着如果您发送()某个东西,并且发送调用会导致稍后发生错误(例如,当TCP/IP堆栈实际发送数据包或ICMP数据包稍后返回时),随后的发送将返回该错误。这种异步错误仅在“连接”的UDP套接字上返回。( linux (7)手册显示,无论套接字是否连接,都会返回错误,但测试表明,至少在发送的UDP数据包生成ICMP错误时,情况并非如此。如果在该套接字上使用recv(),而不是随后的send()调用产生错误,则可能会返回send()错误。
但是套接字没有关闭,您必须通过调用close()或退出程序来自己关闭它。例如,如果连接()您的UDP套接字,并且发送到没有人正在侦听的端口,则通常返回ICMP数据包,随后的send()调用将失败,errno设置为ECONNREFUSED。您可以继续在该套接字上发送,但它不会被操作系统关闭,而且如果有人在数据包通过的同时开始监听端口。
发布于 2011-04-28 19:24:39
UDP套接字是无连接的,因此它们没有真正的“开放性”状态--这与TCP套接字不同,在TCP套接字中,套接字可能处于任意数量的连接状态,这取决于数据包交换到给定点。
UDP套接字可以打开和关闭的唯一意义是,它们是具有某种内部状态和文件描述符的系统级对象。套接字永远不会在发生错误时自动关闭,并且将无限期地打开,除非它们拥有的进程终止或调用它们的close。
为了解决另一个问题,如果目标主机上的目的端口未打开,UDP数据包的发送方将永远不会知道。** UDP不提供接收者确认的方式。该数据包被路由,如果它到达主机,检查其正确性,并成功地接收或丢弃。在写入UDP套接字时,send可能返回错误代码,原因有很多,但它们都与接收主机的状态无关。**我建议向sendto 命令页咨询可能的故障模式。
另一方面,如果TCP套接字试图连接到未打开的端口,发送方将永远不会收到对其初始连接请求的确认,最终connect将失败。此时,应该由发送方停止通过套接字发送数据(因为这只会产生更多的错误),但是即使在这种情况下,套接字文件描述符也不会自动关闭。
**见评论中@Zuljin的答复。
发布于 2011-04-29 07:12:16
操作系统不会仅仅因为发生错误就关闭套接字。如果另一端消失,您可以继续向其发送消息(但可能会收到进一步的错误)。
https://stackoverflow.com/questions/5823723
复制相似问题