在C#中访问给定套接字的TCP重传字节数(和重传数据包数)

时间:2019-12-17 06:18:17

标签: c# .net sockets .net-core tcp

我想将TCPListener / TCPClient与Async回调和IOCP一起用于某些TCP性能软件。

我想做的就是获取当前活动套接字的TCP堆栈已重新传输的字节数。

我注意到mstcpip.h具有结构_TCP_INFO_v0。这包含字段:

typedef struct _TCP_INFO_v0 {
  ...
  ULONG    BytesRetrans;
  ...
}

MS文档指出:

  

要获取此结构的实例,请使用 SIO_TCP_INFO 控制代码调用 WSAIoctl LPWSPIoctl 函数。

我找不到一种通过必要的p / invoke调用来钻取.NET对象的方法。任何人都可以使用TCPClient作为起点来协助代码段吗?

谢谢。

作为专家的额外帮助,获得重传的数据包数量也将是一件很不错的事情,但是我无法为此找到一个变量。我猜想数据包的组装和跟踪将发生在tcp堆栈以下的水平,实际上,两个丢失的顺序数据包可以作为一个数据包重新传输,而一个丢失的数据包可以作为两个甚至更多个数据包重新传输-尽管我从来没有在数据包跟踪中见证了这一点-但后来我也没有那么努力。

1 个答案:

答案 0 :(得分:0)

使用 C提供的注释。 Gonzalez 这是一些似乎有效的代码。它需要对有损连接进行测试,并清理类型和转换。

    struct TCP_INFO_v0
    {
        public UInt32 State;
        public UInt32 Mss;
        public UInt64 ConnectionTimeMs;
        public byte TimestampsEnabled;
        public UInt32 RttUs;
        public UInt32 MinRttUs;
        public UInt32 BytesInFlight;
        public UInt32 Cwnd;
        public UInt32 SndWnd;
        public UInt32 RcvWnd;
        public UInt32 RcvBuf;
        public UInt64 BytesOut;
        public UInt64 BytesIn;
        public UInt32 BytesReordered;
        public UInt32 BytesRetrans;
        public UInt32 FastRetrans;
        public UInt32 DupAcksIn;
        public UInt32 TimeoutEpisodes;
        public byte SynRetrans;
    }

    // SIO_TCP_INFO as defined in winsdk-10/mstcpip.h
    readonly static int SIO_TCP_INFO = unchecked((int)0xD8000027);
    static void Main(string[] args)
    {
        TcpClient tcpClient = new TcpClient("127.0.0.1", 445);

        var outputArray = new byte[128];
        tcpClient.Client.IOControl(SIO_TCP_INFO, BitConverter.GetBytes(0), outputArray);

        GCHandle handle = GCHandle.Alloc(outputArray, GCHandleType.Pinned);
        TCP_INFO_v0 tcpInfo = (TCP_INFO_v0)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(TCP_INFO_v0));
        handle.Free();

        Console.WriteLine("Bytes retransmitted: {0}", tcpInfo.BytesRetrans);

    }