【问题标题】:Can connect() return 0 with non-blocking socket?connect() 可以使用非阻塞套接字返回 0 吗?
【发布时间】:2012-12-25 03:02:45
【问题描述】:

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

man 页面只是说 如果“套接字是非阻塞的并且无法立即完成连接”,它将返回 -1 并将 errno 设置为 EINPROGRESS。

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

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

【问题讨论】:

    标签: linux sockets


    【解决方案1】:

    是的,非阻塞的 connect() 可以返回 0(这意味着成功),尽管 TCP 不太可能发生这种情况。 “立即”意味着内核不必等待来确定状态。您可以看到这种情况的情况包括

    1. UDP 套接字,其中 connect() 基本上是建议性的,允许稍后使用 send(),而不是 sendto()。

    2. 流式处理 UNIX 域套接字,其中对等点位于同一内核中,因此可以立即进行审查。

    3. 到 127.0.0.1 (localhost) 的 TCP 连接。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 感谢您的回复,但似乎我没有明白您的意思。如果同一台机器上的另一个进程忙于其他事情怎么办? Connect() 不会返回 0?那么可能会有超时吗?其实我问的是真实网络存在的情况。
      • 如果数据包必须通过真实网络发送,那么操作系统不会等待回复。本质上,设置套接字非阻塞意味着永远不要等待从远程机器接收到数据包。如果操作系统无需等待即可成功完成connect 调用,那么它将返回 0。通常发生这种情况的唯一情况是您连接到同一台机器上的另一个进程。
      【解决方案3】:

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

      现在,假设您询问 TCP,即使对于非阻塞套接字,也不必这样做,但可以实现 connect(2),以便在条目上启动协议握手,并在返回用户空间检查之前如果它是完整的。然后,由于操作系统网络堆栈对于用户应用程序主要是异步操作的,如果您的进程在系统调用中间被抢占并在稍后切换回,则握手可能已经完成,并且成功为零,返回到应用程序。

      【讨论】:

      • 这就是它的实现方式
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-01
      • 2015-11-27
      • 1970-01-01
      • 2013-06-04
      • 1970-01-01
      • 2010-10-18
      相关资源
      最近更新 更多