一个连接的UDP套接字何时会被操作系统关闭?
When will a connected UDP socket be closed by the OS?
我在Linux下运行的c++程序中有一个UDP文件描述符。我调用connect()
将其连接到远程地址,然后从该套接字读取和写入。
根据UNIX Network Programming,"对于连接的UDP套接字,异步错误将返回给进程。"我猜这些异步错误将导致UDP套接字被操作系统关闭,但这本书不是那么清楚。也不清楚什么类型的异步错误是可能的,尽管建议如果远程机器上的端口未打开,则套接字将被关闭。
所以我的问题是:在什么条件下Linux会关闭UDP文件描述符?
- 端口号错误?
- 错误的IP地址?
- 还有其他的吗?
connect()在UDP套接字上只记录端口号和你传入的IP地址,所以它只接受来自该IP/端口的数据包,并且你可以使用套接字fd来发送/写入数据,而无需为每个发送/写入调用指定远程地址。
关于这一点,异步错误意味着如果你发送()一些东西,并且发送调用导致稍后发生错误(例如,当TCP/IP堆栈实际发送数据包时,或者稍后返回ICMP数据包),随后的发送将返回该错误。这种异步错误仅在"连接"的UDP套接字上返回。linux udp(7)手册建议无论套接字是否连接都返回错误,但测试表明,至少当发送的udp数据包产生ICMP错误时,情况并非如此。如果您在该套接字上recv(),则可能会返回send()错误,而不是随后的send()调用产生错误)
套接字没有关闭,您必须通过调用close()或退出程序来关闭它。例如,如果你connect()你的UDP套接字,并发送到一个端口noone正在监听,一个ICMP数据包通常被返回,随后的send()调用将失败errno设置为ECONNREFUSED。您可以继续在该套接字上发送,它不会被操作系统关闭,如果有人在此期间开始侦听端口,数据包将通过。
UDP套接字是无连接的,因此没有真正意义上的"开放"状态附加到它们上-这与TCP套接字不同,在TCP套接字中,套接字可以处于任意数量的连接状态,由数据包交换决定,直到给定点。
UDP套接字可以打开和关闭的唯一意义是它们是具有一些内部状态和文件描述符的系统级对象。套接字在发生错误时永远不会自动关闭,并且将无限期地保持打开状态,除非它们所属的进程终止或对它们调用close
。
为了解决你的另一个问题,如果目的主机上的目的端口没有打开,UDP数据包的发送者将永远不会知道。UDP不提供接收方确认的方式。数据包被路由,如果它到达主机,则检查其正确性,成功接收或丢弃。send
可能在写入UDP套接字时返回错误代码的原因有很多,但它们都与接收主机的状态无关。**我建议查阅sendto
管理页,了解可能的故障模式。
另一方面,在TCP套接字试图连接到未打开的端口的情况下,发送方将永远不会收到其初始连接请求的确认,最终connect
将失败。此时,将由发送方决定是否停止通过套接字发送数据(因为这只会产生更多错误),但即使在这种情况下,套接字文件描述符也不会自动关闭。
**参见@Zuljin在评论中的回应
操作系统不会因为发生错误而关闭您的套接字。如果另一端消失了,您可以继续向它发送消息(但可能会收到进一步的错误)。
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 字符和 int 连接何时会导致 seg 错误?
- 当使用 std::move 和 lambda 时,何时会发生移动
- thread.detach() 函数的左值何时会超出以下代码的范围
- 传递给协程的临时何时会被销毁?
- 何时会检查执行的类型参数
- 移动构造函数何时会被调用
- 为什么数据类型的大小会随着操作系统的变化而变化
- 何时会出现结构包装问题
- 我可以通过其句柄判断可等待计时器何时会触发
- 何时会隐式实例化导致问题
- CD 上的.exe是否会在没有操作系统的计算机上安装
- 矢量的容量何时会降低
- 何时会在单一实例中删除内存
- 何时正确定义放置新放置,以及调用放置 new 时现有类型会发生什么情况
- 编译器何时不会创建默认构造函数
- 这个函数何时以及为什么会返回其他东西
- string何时会导致类似于c++中的NullPointerException或ArrayOutOfBound索引的错误
- mmap小尺寸内存,当munmap为glibc时,会将映射内存释放到操作系统
- 一个连接的UDP套接字何时会被操作系统关闭?