微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Winsock - 重传序列递增

如何解决Winsock - 重传序列递增

自定义客户端通信时,我得到以下信息。 对于自定义客户端,我指的是带有 FPGA 的自制 PCB,该 PCB 运行三速以太网英特尔 FPGA IP。如果PC和PCB之间有一个开关没有区别。

从服务器(Windows PC)看到的工作流程,我用wireshark检测到这种行为:

  1. 连接到客户端 (Syn - Syn/Ack - Ack) Winsock2.connect
  2. 发送数据 > 使用 Winsock2.WSASend 的 MTU(4088 字节 MTU 上的 4092 字节)
  3. 数据包被“分段”成 2 个数据包 - 未设置分段位
  4. 发生重传(因为客户端响应太慢?)

我正在使用 delphi 10.4 并使用 Winsock2 函数。如果 FD_Isset 设置了 fdwrite,则每次发送时我都会使用 select 检查。 Nagle 已停用。

“重传”不会每次都发生,当它们发生时我无法检测到任何类型的模式。除了大多数时候客户端需要超过 30 毫秒的时间来发送他的 ACK。

当“重传”发生时,重发的不是数据包1或2,而是数据包1的偏移量为60的数据包,这是数据包2的有效载荷。数据包1的序列号也增加了60。即使数据是正确的,它也正确地增加了 60。 当我发送 6000 字节时,我得到了相同的行为,递增的 seq 为 1968,这也是正确的。 这里发生了什么? 我可以用 winsock2 检测到这个吗?我可以用 winsock 设置 RTO 吗?为什么要增加序列号而不是重新传输数据包 1?

发送函数源码:

function TZWinTcpsock.SendData (out ErrMsg : TAPILogStruct; SendOffset : 
Cardinal = 0)  : Boolean;
var
  WSABuff   : WSABUF;
  res       : Integer;
  IPFlags   : Cardinal;
  t         : Cardinal;
  WSAErr    : Cardinal;
begin
  Result      := FALSE;
  WSAErr      := WSAGetLastError;
  try
    if not CheckSockValid(ErrMsg) then // checks if fd_write is set
    begin
      exit(false);
    end;
    try
      WSABuff.len   := FMem.SendLength; // 4092 at this time Cardinal
      WSABuff.buf   := @FMem.SendData[SendOffset]; // 8192 Bytes reserved TArray<Byte>
      IPFlags       := 0;
      res := WSASend(FSocket,@WSABuff,1,FMem.sentBytes,IPFlags,nil,nil);
      if Res <> SOCKET_ERROR then
      begin
        if FMem.SendLength <> FMem.SentBytes then
        begin
          exit(false);
        end
        else
        begin
          Result := TRUE;
          if WSAGetLastError <> WSAErr then // unexpected WSA error
          begin
            exit(FALSE);
          end;
        end;
      end
      else
      begin
        FLastWSAErr       := WSAGetLastError;
        if FLastWSAErr = WSAECONNRESET then
        begin
          disconnect(ErrMsg);
          exit(false);
        end;
      end;
    except
      on E : Exception do
      begin
        // Some error handling
      end;
    end;
  finally
    
  end;
  
end;

Wireshark

编辑 1 数据包设置了不分段位。 我试图用 Windows 管理中心检测这种“重新传输”,但我没有看到任何弹出。

Perfmon

解决方法

Microsoft Q&A 上得到答复。 看起来是目的主机有问题的tail loss probe问题,因为回复时间太长,srtt超时。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。