C# 访问c中给定套接字的TCP重传字节数(和重传数据包数)#
我想将TCPListener/TCPClient与异步回调和IOCP一起用于一些TCP性能软件 我希望能够获得TCP堆栈为当前活动套接字重新传输的字节数 我注意到mstcpip.h具有struct\u TCP\u INFO\u v0。其中包含以下字段:C# 访问c中给定套接字的TCP重传字节数(和重传数据包数)#,c#,.net,sockets,.net-core,tcp,C#,.net,Sockets,.net Core,Tcp,我想将TCPListener/TCPClient与异步回调和IOCP一起用于一些TCP性能软件 我希望能够获得TCP堆栈为当前活动套接字重新传输的字节数 我注意到mstcpip.h具有struct\u TCP\u INFO\u v0。其中包含以下字段: typedef struct _TCP_INFO_v0 { ... ULONG BytesRetrans; ... } MS文档说明: 要获取此结构的实例,请使用SIO\u TCP\u INFO控制代码调用WSAIoctl或L
typedef struct _TCP_INFO_v0 {
...
ULONG BytesRetrans;
...
}
MS文档说明:
要获取此结构的实例,请使用SIO\u TCP\u INFO控制代码调用WSAIoctl或LPWSPIoctl函数
我找不到通过必要的p/invoke调用来钻取.NET对象的方法来获取此信息。有人可以用TCPClient作为起点来帮助编写代码片段吗
谢谢
对于专家来说,获得重新传输的数据包的数量也很好,但是我还没有找到一个变量。我猜数据包组装和跟踪将发生在tcp堆栈之下的某个级别,实际上,两个丢失的连续数据包可以作为单个数据包重新传输,一个丢失的数据包可以作为两个或更多数据包重新传输——尽管我从未在数据包跟踪中看到过这一点——但我一直没有注意到这一点也很难。使用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);
}
对于已建立的TcpClient,您应该能够执行
myTcpClient.Client.IOControl(SIO_TCP_INFO,BitConverter.GetBytes(0),outputArray)
,其中SIO_TCP_INFO=-671088583(0xD800039)和outputArray
是一个大小合适的字节数组(128应该足够了)。outputArray将包含所需的结构,并且可以通过适当的强制转换检索所需的值。IOControl本身将返回输出数组中的相关字节数。@C.Gonzalez不是“(0xD800039)”,而是“(0xD800027)”,因为代码是“\u WSAIORW(IOC\u供应商,39)”。也就是说,39是十进制的,而不是十六进制。@G.Vanem你说得对,错了。