我设置了一个套接字来接受 TCP 连接
socket(AF_INET, SOCK_STREAM, 0)
然后我打电话bind()
给listen()
accept()
问题是当我调用listen() 时,它会导致向客户端发送一个SYN/ACK 数据包。我以为直到我调用了 accept() 才会发生这种情况,但更糟糕的是 SYN/ACK 数据包没有确认增加一。
是什么原因造成的,我该如何解决?
谢谢
作为旁注 - 我的 TCP 连接不对称是否重要?
我设置了一个套接字来接受 TCP 连接
socket(AF_INET, SOCK_STREAM, 0)
然后我打电话bind()
给listen()
accept()
问题是当我调用listen() 时,它会导致向客户端发送一个SYN/ACK 数据包。我以为直到我调用了 accept() 才会发生这种情况,但更糟糕的是 SYN/ACK 数据包没有确认增加一。
是什么原因造成的,我该如何解决?
谢谢
作为旁注 - 我的 TCP 连接不对称是否重要?
您机器上的 TCP 实现可能会选择在您调用时实际“接受”传入连接listen
。这实际上是有道理的,以避免由于“懒惰”接受而导致不必要的延迟。提醒一下,其中一个参数listen
就是所谓的积压数,即“缓冲”接受待处理的数量。
关于syn+ack数据报中ACK的递增。我不记得协议规定了什么,但这可能是握手期间的正确行为。
这是 TCP 'backlog' 队列的正常操作。它是堆栈已经完成但应用程序尚未接受的连接队列。这个队列的大小由listen() 的第二个参数设置,尽管平台可以向上或向下调整它(通常是向上)。
无论您观察到有关序列号的任何内容,都必然是正确的行为,否则将无济于事。
正如其他答案和评论中提到的,这是 TCP 实现的实际标准行为。
如果您坚持通过接受应用程序中的传入连接来明确完成 TCP 握手,则您有平台相关的解决方案。
对于 Windows 堆栈,您可以SO_CONDITIONAL_ACCEPT
在侦听套接字上设置套接字选项。请参阅winsock 文档。