【问题标题】:TCP Half-Open Connections, Winsock, Listen/Accept BehaviorTCP 半开连接、Winsock、侦听/接受行为
【发布时间】:2017-01-05 17:00:27
【问题描述】:

作为一名网络工程师,我对 TCP 操作非常熟悉。作为一名程序员,我涉足过套接字编程,但从未编写过任何生产服务。

我们有一个与 PTZ(平移/倾斜/变焦)摄像机集成的供应商系统。摄像机观察病人。相机数据被馈送到供应商服务器。供应商服务器将相机数据中继给客户端。 (它做得更多,但这是简单的情况。)如果客户端想要调整相机,客户端将自定义命令发送到供应商服务器上的自定义服务。服务器解释命令并将其发送到相机。相机移动。

我们遇到了服务器上的 PTZ 服务崩溃的问题。在测试过程中,通过网络捕获,我们发现服务在nmap 执行半开(胚胎)连接时崩溃了——nmap 发送了 SYN,服务器回复了 SYN/ACK,nmap 没有发送最终的 ACK。服务器发送重复的 SYN/ACK 以尝试完成会话并失败。

我想了解的是:服务使用listen 来监视TCP 连接,然后使用accept 来接受连接。在什么时候listen 告诉服务有一个新的连接,准备好accepted? TCP 连接是否需要在listen 将其传递给服务以成为accepted 之前完成?还是服务器只需要在listen 告诉服务之前返回一个SYN/ACK?

如果握手需要在listen 告诉服务之前完成——SYN、SYN/ACK、ACK,那么我可能走错了路。如果套接字只需要获得 SYN/ACK,则服务处理不完整会话可能存在问题。其他测试,我们完成一个 TCP 会话并发送虚假数据试图让服务崩溃——并没有导致服务失败。但是重复的nmap 测试相当可靠地崩溃了,所以我倾向于半开连接问题。

【问题讨论】:

    标签: sockets tcp winsock listen


    【解决方案1】:

    listen()本身只是简单的创建积压队列,打开绑定端口进行通信,然后退出。 在幕后,套接字堆栈现在被动地侦听操作系统层的连接,缓存待处理的连接在积压队列中并完成它们的握手。只有完全建立的连接对accept()WSAAccept()AcceptEx() 可用。

    listen() 退出后,取决于应用程序代码用于套接字 I/O 的模式(阻塞、非阻塞、重叠 I/O 或 I/O 完成端口),代码可以:

    1. (阻塞)调用accept()WSAAccept() 并让它阻塞直到它从队列中检索到一个连接。

    2. (非阻塞)使用select()WSAAsyncSelect()WSAEventSelect() 在连接准备好并等待通过accept()WSAAccept() 检索时收到通知。

    3. (overlapped/iocp) 调用 AcceptEx() 开始异步接受,然后等待指示已从队列中检索到连接的事件/完成通知。

    【讨论】:

    • 我想我明白了。因此,想象一下作为供应商系统的黑匣子,供应商可能坐在select() 而不是listen()。所以在第 2 点,当连接“准备好并等待”时。 . .这是否意味着握手已完成?客户端发送了 TCP ACK?或者它仍然可以“准备好并等待”等待最终的客户端 ACK?
    • 正如我在回答中所说:“只有完全建立的连接可用于accept(), ...”。所以是的,连接的握手必须在代码看到连接之前完成。
    • 谢谢雷米。非常感谢。这表明半开连接不会破坏服务,所以它一定是发送到服务的东西。但我们只是无法确定它是什么。现在我了解了listen()select()accept() 如何协同工作以及与协议栈一起工作,我会继续寻找。再次感谢!
    【解决方案2】:

    listen 在什么时候告诉服务有一个新的连接,准备好被接受了?

    从不。

    在listen将它传递给服务之前,TCP连接是否需要完成才能被接受?还是服务器只需要在 listen 告诉服务之前返回一个 SYN/ACK ?

    这一切都不会发生。 listen() 只是将套接字置于 LISTEN 状态,并导致 TCP 开始接受连接并将它们放入积压队列中。与服务通信的是accept():它在积压队列为空时(基本上)阻塞,然后返回第一个条目并围绕它构造一个新的套接字。

    如果握手需要完成——SYN、SYN/ACK、ACK——在listen告诉服务之前,那么我可能走错了路。

    需要在accept() 向服务返回一个新套接字之前完成。

    如果套接字只需要获得 SYN/ACK,则服务处理不完整会话可能存在问题。

    不是问题。它的行为不是那样的。

    在其他测试中,我们完成了 TCP 会话并发送虚假数据以试图让服务崩溃,但并未导致服务失败。

    QED。

    但重复的 nmap 测试相当可靠地导致它崩溃,所以我倾向于半开连接问题。

    请定义“崩溃”。

    【讨论】:

    • 供应商服务,因此不能明确说明“崩溃”。 “锁定”可能是一个更好的术语,但我们无法确定。没有日志条目。客户端和服务器屏幕上的摄像头控件灰显,无法移动摄像头,有时摄像头会在故障时随机指向不同的方向。重启 PTZ 服务 5 次中有 4 次;其他时候服务器需要重新启动。供应商说端口扫描已知会导致问题。我们正在尝试确定确切的情况和原因,以便我们可以告诉供应商修复您的东西。
    猜你喜欢
    • 2021-12-16
    • 2013-02-17
    • 1970-01-01
    • 2011-12-10
    • 2021-01-17
    • 1970-01-01
    • 2022-11-02
    • 2011-05-21
    • 1970-01-01
    相关资源
    最近更新 更多