Winsock TCP重传/重置协议详细信息

时间:2014-07-16 18:41:33

标签: windows sockets networking tcp winsock

首先是一点背景:

我目前有一个通过TCP与服务器通信的客户端。客户端和服务器都运行Windows并使用WinSocks。我向服务器发送各种消息,每秒至少发送一条消息。几乎就是每10分钟,我看到一个问题,我的服务器似乎停止回复我的客户端。然后我看到来自客户端的5次重传,每次使用超时加倍,然后最终从服务器在客户端上接收RST包。这将重置我的客户端套接字,分配一个新的端口号,然后通信继续正常,再持续10分钟。

现在有点数据:

我正在使用wireshark来分析这个问题。所有数据都在连接的客户端(192.168.110.1)侧捕获,因为服务器不易访问。下面是相关数据(抱歉可怕的格式化。这是我在这里得到数据的唯一方法):

RefNum|Source|Destination|Length|Packet Info

1 | 192.168.110.1 | 192.168.110.22 | 61 | 62314 > 7074 [PSH, ACK] Seq=693 Ack=8483 Win=63303 Len=7

2 | 192.168.110.1 | 192.168.110.22 | 75 | [TCP Retransmission] 62314 > 7074 [PSH, ACK] Seq=693 Ack=8483 Win=63303 Len=21

3 | 192.168.110.1 | 192.168.110.22 | 75 | [TCP Retransmission] 62314 > 7074 [PSH, ACK] Seq=693 Ack=8483 Win=63303 Len=21

4 | 192.168.110.1 | 192.168.110.22 | 89 | [TCP Retransmission] 62314 > 7074 [PSH, ACK] Seq=693 Ack=8483 Win=63303 Len=35

5 | 192.168.110.1 | 192.168.110.22 | 113 | [TCP Retransmission] 62314 > 7074 [PSH, ACK] Seq=693 Ack=8483 Win=63303 Len=59

6 | 192.168.110.1 | 192.168.110.22 | 135 | [TCP Retransmission] 62314 > 7074 [PSH, ACK] Seq=693 Ack=8483 Win=63303 Len=81

7 | 192.168.110.22 | 192.168.110.1 | 64 | 7074 > 62314 [RST] Seq=8483 Win=0 Len=0 [ETHERNET FRAME CHECK SEQUENCE INCORRECT]

8 | 192.168.110.1 | 192.168.110.22 | 66 | 62348 > 7074 [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=256 SACK_PERM=1

9 | 192.168.110.22 | 192.168.110.1 | 64 | 7074 > 62348 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460 [ETHERNET FRAME CHECK SEQUENCE INCORRECT]

10 | 192.168.110.1 | 192.168.110.22 | 54 | 62348 > 7074 [ACK] Seq=1 Ack=1 Win=64240 Len=0

11 | 192.168.110.1 | 192.168.110.22 | 56 | 62348 > 7074 [PSH, ACK] Seq=1 Ack=1 Win=64240 Len=2

12 | 192.168.110.22 | 192.168.110.1 | 72 | 7074 > 62348 [PSH, ACK] Seq=1 Ack=3 Win=5838 Len=18

1 - 6 - 原始和重新传输的数据包
7 - 从服务器收到重置
8 - 10 - 客户端和服务器之间的新握手,具有新的客户端端口号
11 - 12 - 第一个新消息和具有新客户端端口号的响应

最后,提出几个问题:

因为现在最明显的是,我不是TCP大师(甚至是关闭)。我认为谷歌对我很强,但我似乎无法追查以下问题的答案:

  1. 我注意到TCP RST数据包来自我正在谈论的服务器,因为该服务器没有回复我的任何其他数据包。这实际上是这种情况,还是有一些TCP技巧在这里使我的客户端端口“认为”这个数据包来自服务器,当它实际上是在客户端发起,试图重置自己。
  2. 套接字是否可以进入可以发送但未接收的状态?这可以解释我所看到的行为,但仍然没有解释我如何能够接收RST数据包,除非我在1中的假设是正确的。
  3. 我注意到重传数据包的大小正在增长......对于TCP来说这是正常的吗?看来我的客户端试图发送到服务器的其他数据包被集中到重新传输的TCP数据包中。其他所有东西似乎都正常运行(超时加倍等)。
  4. 提前感谢您的时间。

1 个答案:

答案 0 :(得分:0)

您的问题的答案:

  1. 客户端将RST发送给自己并欺骗服务器是非常值得怀疑的。如果确实如此,你可能不会在电线上看到它。查看src和dst MAC地址,它们是否与来自服务器的其他流量相同?
  2. 是的,如果接收缓冲区已满,则无法再接收任何内容,但它可以发送窗口更新,或者可能是其他方向的数据。
  3. 是的,这很正常。这是电话repacketization。如果应用程序有更多数据要发送,TCP会将其添加到重新发送。
  4. 有两件事让我想知道RST不是来自服务器,而是来自中间设备或主机防火墙:

    1. 如果通信已发生10分钟,则服务器已收到数据并已确认。根据我的经验,在这种情况下,RST将包含一个ACK号,但RST不会。
    2. 一直持续10分钟。听起来像防火墙或代理超时。
    3. 如果是服务器应用程序问题(进程出现问题并停止从套接字读取数据),服务器上的TCP仍会确认接收数据,但其接收窗口将填满。在这种情况下,由于没有ACK,似乎客户端的数据包被丢弃或被阻塞在其间的某个地方。