【发布时间】:2012-12-25 03:02:45
【问题描述】:
对于非阻塞网络套接字,connect()可以返回0吗?
man 页面只是说 如果“套接字是非阻塞的并且无法立即完成连接”,它将返回 -1 并将 errno 设置为 EINPROGRESS。
“立即”到底是什么意思?
如果connect()在这种情况下可以返回0,那么在什么情况下它会返回代表成功的0?当客户端和服务器之间的网络非常好?还是?
【问题讨论】:
对于非阻塞网络套接字,connect()可以返回0吗?
man 页面只是说 如果“套接字是非阻塞的并且无法立即完成连接”,它将返回 -1 并将 errno 设置为 EINPROGRESS。
“立即”到底是什么意思?
如果connect()在这种情况下可以返回0,那么在什么情况下它会返回代表成功的0?当客户端和服务器之间的网络非常好?还是?
【问题讨论】:
是的,非阻塞的 connect() 可以返回 0(这意味着成功),尽管 TCP 不太可能发生这种情况。 “立即”意味着内核不必等待来确定状态。您可以看到这种情况的情况包括
UDP 套接字,其中 connect() 基本上是建议性的,允许稍后使用 send(),而不是 sendto()。
流式处理 UNIX 域套接字,其中对等点位于同一内核中,因此可以立即进行审查。
到 127.0.0.1 (localhost) 的 TCP 连接。
【讨论】:
在这种情况下,“立即”意味着无需等待通过网络从另一台机器接收到数据。如果它可以立即完成,则可以返回零。例如,如果它正在连接到同一台机器上的另一个进程,内核可以立即完成连接过程。
【讨论】:
connect 调用,那么它将返回 0。通常发生这种情况的唯一情况是您连接到同一台机器上的另一个进程。
connect(2) 是系统调用,即进入内核的入口。这是多任务操作系统抢占您的进程做其他事情的机会。
现在,假设您询问 TCP,即使对于非阻塞套接字,也不必这样做,但可以实现 connect(2),以便在条目上启动协议握手,并在返回用户空间检查之前如果它是完整的。然后,由于操作系统网络堆栈对于用户应用程序主要是异步操作的,如果您的进程在系统调用中间被抢占并在稍后切换回,则握手可能已经完成,并且成功为零,返回到应用程序。
【讨论】: