【问题标题】:Can 'connect' call on socket return successfully without server calling 'accept'?可以在没有服务器调用“接受”的情况下成功返回套接字上的“连接”调用吗?
【发布时间】:2011-01-25 10:35:21
【问题描述】:

服务器创建了一个套接字并绑定到一个端口并启动了一个正在循环中的线程以接受连接。稍后循环由于异常导致线程退出而退出,但套接字仍然绑定到端口。现在,如果客户端“连接”到该服务器,它就成功了。这怎么可能?如果我理解正确,则仅在服务器在侦听套接字上“接受”后才返回“连接”。我在这里遗漏了什么吗?

【问题讨论】:

    标签: linux sockets tcp network-programming


    【解决方案1】:

    连接的套接字进入队列等待接收进程接受()它们。这些积压是有限的,一旦达到,操作系统将开始拒绝连接或忽略它们。

    【讨论】:

    • 我的问题是“连接”调用何时返回?服务器在连接套接字上调用“接受”之后或成功进入侦听队列后?如果服务器不调用“接受”,我们可以期待客户端中的“连接”成功吗?
    • 你不正确,connect 不会等待服务器调用accept()。它只等待来自操作系统的响应,通常会将请求排队。
    【解决方案2】:

    如果我理解正确,“连接”仅在服务器在侦听套接字上“接受”后才会返回。我在这里遗漏了什么吗?

    是的。 TCP 在幕后建立连接 - 3 次握手 - 并在准备好时将其放入已完成的连接队列中。 Accept() 从这个队列的前面返回下一个等待连接。

    从客户端的角度来看,它是“连接的”,但在服务器接受并开始处理之前它不会与任何人交谈。有点像当您致电一家公司并立即进入等待队列时。您已“连接”,但在有人真正接起并开始讲话之前,您不会做任何事情。

    您的单个​​线程可能已经死亡,但进程仍然存在,并且文件描述符仍然打开,因此 TCP 不知道应用程序级别发生了什么。

    【讨论】:

    • 电话服务保持队列和尚未接受()的 TCP 连接之间的区别:沿着 TCP 连接发送的任何字节都由操作系统缓冲,并且只接收一次已经调用了 accept()。在电话系统保持线上,呼叫者所说的任何内容都会被丢弃。
    • 我在考虑是否要添加,所以谢谢。当然,没有什么可说的,电话服务没有在您认为您处于等待状态并且正在播放 muzak 时为您录音。 :)
    • 还值得指出的是,这就是 backlog 调用的 backlog 参数的全部意义 - 积压是可以在该连接但未连接的连接数任何时候都接受的状态。
    • 优秀。现在我更好地理解了这种行为。非常感谢 Duck 和 Heath。
    • 服务器(调用accept())是否只有在accept()返回时才花费一个文件描述符?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-14
    • 2015-04-03
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    相关资源
    最近更新 更多