【问题标题】:two (wrong) connections on a socket that uses listen(1)使用 listen(1) 的套接字上的两个(错误)连接
【发布时间】:2015-12-10 17:42:12
【问题描述】:

我正在用 C++ 开发两个使用 C Linux 套接字调用的应用程序,一个服务器和一个客户端。 服务器侦听特定端口 A 并使用接受函数检索连接。 我正在使用 int result = ::listen(mySocketFileDescriptor, 1);将最大连接数限制为 1。 顺便说一句,在服务器中,我使用 SO_REUSEADDR 选项来重用套接字以用于其他原因。

如果客户端有多个断开/连接,有时会发生奇怪的行为: 例如,客户端成功连接到服务器,但是当它发送数据时,服务器没有收到任何东西。

在客户端应用程序中,我使用 Linux 自动分配的端口连接到端口 A,我们称之为 B。 使用 netstat 我发现客户端都从套接字连接到服务器到端口 A 它使用端口 B,而另一个使用另一个端口 C。我已经调试过,我已经看到 服务器从使用 B 的套接字读取,而客户端在使用 C 的套接字上写入。

知道这种行为的原因吗?

除了我的代码可能存在的任何可能的逻辑问题之外,是否可以使服务器 建立新连接时总是丢弃旧连接?有什么可以设置的选项吗?

提前谢谢你!

【问题讨论】:

    标签: c linux sockets network-programming unix-socket


    【解决方案1】:

    网络连接一端的机器识别另一端已断开连接并不容易。特别是,如果远端突然切断连接,而不是正确关闭它,这样做是非常困难的。

    此外,没有什么能阻止相同的两台机器同时建立多个连接。如果您想将其限制为一个,那么您的服务器需要跟踪它当前连接到的客户端,并且它必须准备好同时为多个连接提供服务,以便识别何时有新连接由现有客户建立。这需要多路复用(例如使用select())或多处理。然后,如果它从已有客户端的客户端接收到新连接,则服务器会停止处理旧连接并将其关闭。

    【讨论】:

    • 在我的测试中总是有相同的客户端,所以相同的 IP 地址。当您谈论“处理旧连接”时,您是什么意思?我已经每次都关闭了旧套接字,但似乎没有解决问题
    • @user3770392,你描述的netstat测试显示服务器机器与客户端同时建立了两个连接。至少在它的末端是这样的——可能其中一个在客户端是关闭的,但显然服务器没有认识到这一点。首先建立的是“旧”的。服务器 program 可能还没有accept()ed 新连接,但这是一个完全不同的问题。服务器必须accept() 新连接才能识别它应该丢弃旧连接。这就是您需要处理多个连接的原因。
    • @user3770392,另外,请确保您处理所有函数调用的错误结果。可能是系统已经告诉服务器程序断线了,但是服务器忽略了。
    • 布林格:谢谢你的建议。更多信息:客户端的 PID 建立了 2 个连接,而服务器只有一个(使用旧端口)。我刚刚尝试接受然后销毁旧套接字(用指针保存它)但仍然是同样的问题。
    【解决方案2】:

    您需要更彻底地阅读listen manual page,因为“限制”不是可以与该套接字建立的最大连接数,而是可以尝试在您之前同时连接的连接数的限制致电accept。一旦您致电accept,就可以建立另一个连接。

    许多示例中的“标准”值是5,但这些服务器可以处理数百个连接。

    【讨论】:

    • 你是对的,我的错。我想读一些其他的 TCP/IP 书籍,请随时给我推荐一本。无论如何,我认为这不是服务器中的问题,在接受之前我关闭并删除了旧套接字
    • 关于书籍,我正在考虑阅读:W. Richard Stevens,Unix 网络编程,第 1 卷:套接字网络 API,但它似乎很旧
    • @user3770392 它仍然是该领域的权威教科书之一。
    猜你喜欢
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-31
    • 2011-07-31
    • 2014-01-26
    • 1970-01-01
    相关资源
    最近更新 更多