非阻塞套接字在调用connect()时是否可能返回0?

4

对于非阻塞的网络套接字,connect()是否可以返回0?

man手册只说:如果“该套接字是非阻塞的且连接不能立即完成”,则它将返回-1并将errno设置为EINPROGRESS。

“立即”到底是什么意思?

如果在这种情况下,connect()可能返回0,那么它会在何种情况下返回0,表示成功?当客户端和服务器之间的网络非常好时吗?还是其他情况?

3个回答

2
是的,非阻塞的connect()可以返回0(表示成功),尽管这在TCP中不太可能发生。 "立即"的意思是内核无需等待以确定状态。您可能会看到以下情况:
  1. UDP套接字,其中connect()基本上是指导性的,允许稍后使用send(),而不是sendto()。

  2. 流UNIX域套接字,其中同行在同一个内核中,因此可以立即进行审查。

  3. 与127.0.0.1(localhost)建立的TCP连接。


1
在这个上下文中,“立即”意味着不等待通过网络从另一台机器接收数据。如果可以立即完成,则可以返回零。例如,如果它正在连接同一台机器上的另一个进程,则内核可以立即完成连接过程。

谢谢您的回复,但似乎我没有理解您的意思。如果同一台机器上的另一个进程正在忙于其他事情,那怎么办?Connect() 不会返回 0 吗?所以可能会超时?实际上,我是在询问真实网络存在的情况下的情况。 - Jacky
1
如果要通过真实网络发送数据包,操作系统将不会等待回复。基本上,将套接字设置为非阻塞意味着永远不等待从远程计算机接收数据包。如果操作系统可以成功完成“连接”调用而无需等待,则它将返回0。通常仅在您连接到同一台计算机上的另一个进程时才会发生这种情况。 - David Schwartz

1

connect(2)是一个系统调用,也就是进入内核的入口。这是多任务操作系统抢占您的进程去做其他事情的机会。

现在,假设您正在询问TCP,即使对于非阻塞套接字,它也不必如此,但connect(2)可以被实现为在进入时启动协议握手,并在返回到用户空间之前检查是否完成。然后,由于操作系统网络堆栈与用户应用程序大多是异步操作的,如果您的进程在系统调用中间被抢占并在以后的某个时间点切换回来,则握手可能已经完成,并且成功返回给应用程序的是零。


那就是它的实现方式。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接