在非阻塞流套接字连接时调用getsockname()是否安全?

时间:2014-08-15 20:14:47

标签: c linux sockets posix nonblocking

如果我创建了一个流套接字,并且我将其设置为非阻塞,并且我请求它连接到远程主机并且connect()调用返回EINPROGRESS,那么发出{{{ 1}}调用它并期望返回的本地地址是正确的吗?

2 个答案:

答案 0 :(得分:3)

getsockname返回套接字绑定的地址。从connect开始的第一件事是将套接字绑定到本地地址和端口(除非它已经被用户绑定)。这是一个本地和非阻塞操作。因此,即使连接仍在进行中,您也应该从getsockname获取可用值。

对于这个论证,我假设您只在使用EINPROGRESS返回的connect调用之后调用getsockname,而不是在connect尚未返回时调用另一个线程。论证也是基于以下事实:没有为绑定系统调用非阻塞套接字定义的特殊行为。这表明绑定本身不会阻止。此外,路由表中的查找以确定用于连接的本地地址也应仅使用现有的内核数据,因此不会阻塞。

答案 1 :(得分:1)

因为这个问题被标记为Linux:我查找了源代码(内核3.4.103 af_inet.c: inet_stream_connecttcp_ipv4.c: tcp_v4_connect)并发现连接到非阻塞(IPv4)套接字确实是以这种方式实现的{/ 3}} 设置本地套接字地址后设置EINPROGRESS:端口已执行且之前连接&# 39;握手已经建立。

所以(至少对于内核3.4.103),对connect()的调用应该是安全的。

但POSIX没有指定此行为(getsocketname()),所以不要依赖于此。