TCP半开连接,Winsock,侦听/接受行为

时间:2016-08-29 15:35:57

标签: sockets tcp winsock listen

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

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

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

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

如果握手需要完成 - SYN,SYN / ACK,ACK - 在listen告诉服务之前,那么我可能会走错路。如果套接字只需要进入SYN / ACK,则服务处理不完整的会话可能会出现问题。其他测试,我们完成TCP会话并发送伪造数据试图使服务崩溃 - 并未导致服务失败。但重复的nmap测试非常可靠地崩溃了,所以我倾向于半开连接问题。

2 个答案:

答案 0 :(得分:0)

listen()本身只是创建积压队列,打开绑定端口进行通信,然后退出。 在幕后,套接字堆栈现在被动地侦听OS层的连接,缓存积压队列中的挂起连接并完成他们的握手。只有完全建立的关联可用于accept()WSAAccept()AcceptEx()

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

  1. (阻止)调用listen()accept()并让它阻塞,直到它从队列中检索连接。

  2. (非阻止)使用WSAAccept()select()WSAAsyncSelect()在连接准备好并等待使用WSAEventSelect()accept()

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

答案 1 :(得分:0)

  

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

从不。

  

在将侦听传递给要接受的服务之前,TCP连接是否需要完成?或者服务器是否需要在监听告诉服务之前返回SYN / ACK?

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

  

如果握手需要完成 - SYN,SYN / ACK,ACK - 在监听告诉服务之前,那么我可能会走错路。

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

  

如果套接字只需要进入SYN / ACK,则服务处理不完整的会话可能会出现问题。

不是问题。它的行为并非如此。

  

其他测试,我们完成TCP会话并发送虚假数据试图让服务崩溃 - 但没有导致服务失败。

QED。

  

但重复的nmap测试非常可靠地崩溃了,所以我倾向于半开连接问题。

请定义'崩溃'。