首页 文章

操作系统何时关闭连接的UDP套接字?

提问于
浏览
2

我在Linux下运行的C程序中有一个UDP文件描述符 . 我在其上调用 connect() 将其连接到远程地址,然后从该套接字读取和写入 .

根据UNIX网络编程,"Asynchronous errors are returned to the process for connected UDP sockets."我很清楚 . 建议如果远程机器上的端口未打开,则套接字将被关闭 .

所以我的问题是:在什么条件下Linux会关闭UDP文件描述符?

  • 端口号错误?

  • 错误的IP地址?

  • 还有其他人吗?

3 回答

  • 5

    UDP套接字上的connect()只记录您传入的端口号和IP地址,因此它只接受来自该IP /端口的数据包,您可以使用套接字fd发送/写入数据而不指定远程地址每个发送/写入呼叫 .

    对此,异步错误意味着如果您发送()某些内容,并且发送调用导致稍后发生错误(例如,当TCP / IP堆栈实际发送数据包,或稍后返回ICMP数据包时),后续发送将返回那个错误 . 此类异步错误仅在“已连接”的UDP套接字上返回 . (linux udp(7)联机帮助页建议无论套接字是否已连接都会返回错误,但测试显示至少在发送的UDP数据包生成ICMP错误时不会出现这种情况 . 可能是返回了send()错误如果你在那个套接字上recv(),而不是后续的send()调用产生错误)

    套接字没有关闭,你必须通过调用close()或退出程序自己关闭它 . 例如如果您连接()您的UDP套接字,并发送到没有人正在侦听的端口,则通常会返回ICMP数据包,并且后续的send()调用将失败,并且errno设置为ECONNREFUSED . 您可以继续发送该套接字,但它不会被操作系统关闭,并且如果有人在平均时间内开始侦听端口,则数据包将通过 .

  • 1

    UDP套接字是无连接的,因此没有真正意义上的“开放”状态 - 这与TCP套接字不同,其中套接字可以处于任意数量的连接状态,如通过直到给定点的数据包交换所确定的 .

    UDP套接字可以打开和关闭的唯一意义是它们是具有某种内部状态和文件描述符的系统级对象 . 套接字在发生错误时永远不会自动关闭,并且将无限期地保持打开状态,除非它们的拥有进程终止或对它们调用 close .

    为了解决您的其他问题,如果未打开目标主机上的目标端口,UDP数据包的发送方将永远不会知道 . ** UDP不提供接收方确认 . 数据包被路由,如果它到达主机,则检查其是否正确并成功接收或丢弃 . send 在写入UDP套接字时可能会返回错误代码有很多原因,但没有一个与接收主机的状态有关 . **我建议查阅 sendto manpage以了解可能的故障模式 .

    另一方面,在TCP套接字尝试连接到未打开的端口的情况下,发送方永远不会收到其初始连接请求的确认,最终 connect 将失败 . 此时,发送方将停止通过套接字发送数据(因为这只会产生更多错误),但即使在这种情况下,套接字文件描述符也永远不会自动关闭 .

    **请参阅评论中@Zuljin的回复 .

  • 5

    操作系统不会因为发生错误而关闭套接字 . 如果另一端消失,您可以继续向其发送消息(但可能会收到更多错误) .

相关问题