数据重新传输和WSAECONNABORTED(10053)套接字错误


4

假设我有两个相互连接的插座( Socket ASocket B )。

如果有的电脑 Socket B 拔掉电源,如果 Socket A 尝试发送一些数据 Socket B,数据将不会得到确认,因此TCP将一次又一次地重新传输数据,希望得到确认,直到TCP放弃并决定不再重新传输数据并告诉 Socket A 那个套接字错误 WSAECONNABORTED (10053) 已经发生了。

我的问题是:

  • 是否保证我将始终收到套接字错误 WSAECONNABORTED (10053) 一些重传重试后(我相信它是,因为否则TCP将继续永远重传!)?
  • TCP决定放弃并导致重启的重试次数 WSAECONNABORTED (10053) 套接字错误?
  • 这个重传重试次数是否可配置?

Answers:


1

TCP的Windows计时器使用一个称为的时间单位 重传超时 (RTO)基于估计 往返时间 (或RTT)发送方和接收方之间,以及此往返时间的差异。此计时器的行为在。中指定 RFC 6298 。 有关更多信息,请参阅Wikipedia文章 传输控制协议

它在Windows中的工作方式如下:

  1. 首先建立估计的RTO
  2. 发送TCP消息,我们等待ACK(确认)数据包
  3. 如果ACK尚未到达,我们将等待时间加倍并返回步骤2
  4. 如果接收到ACK,则计算新的RTO
  5. 如果从未收到ACK,则连接中止,错误为WSAECONNABORTED。

Windows使用此协议的两个注册表参数,如本Microsoft文章中所述
如何修改TCP / IP最大重传超时

TcpMaxDataRetransmissions的

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters

Value Name:  TcpMaxDataRetransmissions
Data Type:   REG_DWORD - Number
Valid Range: 0 - 0xFFFFFFFF
Default:     5

说明:

此参数控制TCP重新传输的次数   中止之前的个别数据段(非连接段)   连接。重传超时每次加倍   连接上的连续重传。响应时重置   恢复。基本超时值由动态确定   测量连接的往返时间。

TCPInitialRtt

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\ID for Adapter

Value Name:  TCPInitialRtt
Data Type:   REG_DWORD
Valid Range: 300-65535 (milliseconds in decimal)
Default:     0xBB8 (3000 milliseconds expressed in hexadecimal)

描述:

此参数控制初始重新传输超时   TCP在每个新连接上使用。它适用于连接   请求(SYN)以及在每个数据段上发送的第一个数据段   连接。例如,“5000十进制”的值数据设置   初始重传时间为五秒。

注意:您只能为初始超时增加该值。   不支持减小该值。

虽然TCPInitialRtt以初始超时开始 3秒,它将被平滑到更多 正确传输数据包时的合理值。

例如,这是如何工作的, 如果我们采用默认值3秒RTO和5次重试, 总等待时间将是:

  1. 第一次超时时间:3秒
  2. 第二次超时:6秒
  3. 第三次超时:12秒
  4. 第四次超时:24秒
  5. 第五次和最后一次超时:48秒

在连接中止之前,总等待时间为93秒。 在大多数情况下,如果连接已正常工作,则超时 将会少得多。


0

一般 时间 用来 ( 继续重试,直到达到超时值 ),但这取决于客户端/服务器软件的编写方式。

如果使用时间,那么为了知道您必须知道的重试次数 多常 重试发生了。

如果程序使用Winsock,请参阅下面的设置超时的可能方法。

该软件也可以编写使用 重试次数 在失败之前或 时间 在失败之前或两者兼而有之。


资源 Winsock程序员的常见问题解答

2.15 - 如何更改Winsock函数的超时?

一些阻塞的Winsock函数(例如connect())有一个超时   嵌入其中。这背后的理论是只有堆栈才有   设置正确超时所需的所有信息。然而,一些   人们发现堆栈使用的值太长了   应用;它可以是一分钟或更长。

您可以使用SO_SNDTIMEO和调整send()和recv()超时   SO_RCVTIMEO setsockopt()选项。 。

对于其他Winsock函数,最好的解决方案是避免阻塞   完全插座。所有非阻塞套接字方法都提供   您可以构建自定义超时的方法:

  • 带select()的非阻塞套接字 - select()函数的第五个参数是超时值。

  • 异步套接字 - 使用Windows API SetTimer()。

  • 事件对象 - WSAWaitForMultipleEvents()具有超时参数。

  • 等待计时器 - 调用CreateWaitableTimers()来创建一个等待计时器,然后可以将其传递给类似WSAEventSelect()的函数   以及你的套接字:如果以前没有任何套接字发出信号   计时器熄灭,阻塞功能无论如何都会返回。

请注意,对于异步和非阻塞套接字,您可以使用   避免完全处理超时。你的程序继续工作   即使在Winsock忙碌的时候。因此,您可以将其留给用户   取消花费太长时间的操作,或者只是让Winsock's   自然超时到期而不是接管此功能   你的代码。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.