C#如何使用GetTcpTable API获取TCP/IP连接信息
C#中如何使用GetTcpTable API函数来取得本机的连接信息
代码已经加了详细注释,我想有需要的同志一定会看得明白了

1 public class NativeFunc 2 { 3 [StructLayout(LayoutKind.Sequential)] 4 public class MIB_TCPROW 5 { 6 public int dwState; 7 public int dwLocalAddr; 8 public int dwLocalPort; 9 public int dwRemoteAddr; 10 public int dwRemotePort; 11 } 12 [StructLayout(LayoutKind.Sequential)] 13 public class MIB_TCPTABLE 14 { 15 public int dwNumEntries; 16 public MIB_TCPROW[] table; 17 } 18 [DllImport("Iphlpapi.dll")] 19 static extern int GetTcpTable(IntPtr pTcpTable, ref int pdwSize, bool bOrder); 20 [DllImport("Iphlpapi.dll")] 21 static extern int SendARP(Int32 DestIP, Int32 SrcIP, ref Int64 MacAddr, ref Int32 PhyAddrLen); 22 [DllImport("Ws2_32.dll")] 23 static extern Int32 inet_addr(string ipaddr); 24 [DllImport("Ws2_32.dll")] 25 static extern ushort ntohs(ushort netshort); 26 //SendArp获取MAC地址 27 public static string GetMacAddress(string macip) 28 { 29 StringBuilder strReturn = new StringBuilder(); 30 try 31 { 32 Int32 remote = inet_addr(macip); 33 Int64 macinfo = new Int64(); 34 Int32 length = 6; 35 SendARP(remote, 0, ref macinfo, ref length); 36 string temp = System.Convert.ToString(macinfo, 16).PadLeft(12, '0').ToUpper(); 37 int x = 12; 38 for (int i = 0; i < 6; i++) 39 { 40 if (i == 5) { strReturn.Append(temp.Substring(x - 2, 2)); } 41 else { strReturn.Append(temp.Substring(x - 2, 2) + ":"); } 42 x -= 2; 43 } 44 return strReturn.ToString(); 45 } 46 catch 47 { 48 return string.Empty; 49 } 50 } 51 public static bool IsHostAlive(string strHostIP) 52 { 53 string strHostMac = GetMacAddress(strHostIP); 54 return !string.IsNullOrEmpty(strHostMac); 55 } 56 public static MIB_TCPTABLE GetTcpTableInfo() 57 { 58 //声明一个指针准备接受Tcp连接信息 59 IntPtr hTcpTableData = IntPtr.Zero; 60 //声明hTcpTableData指针所指向的内存缓冲区大小 61 int iBufferSize = 0; 62 //声明MIB_TCPTABLE对象,作为返回值 63 MIB_TCPTABLE tcpTable = new MIB_TCPTABLE(); 64 65 //声明一个List对象来临时存放MIB_TCPROW对象 66 List<MIB_TCPROW> lstTcpRows = new List<MIB_TCPROW>(); 67 68 //调用API来获得真正的缓冲区大小,iBufferSize默认为0, 69 //这时调用API GetTcpTable会触发一个异常ERROR_INSUFFICIENT_BUFFER 70 //通过这个异常系统会把真正的缓冲长度返回 71 GetTcpTable(hTcpTableData, ref iBufferSize, false); 72 //为托管指针在堆上分配内存 73 hTcpTableData = Marshal.AllocHGlobal(iBufferSize); 74 //求得MIB_TCPROW对象的内存字节数 75 int iTcpRowLen = Marshal.SizeOf(typeof(MIB_TCPROW)); 76 //根据上面得到的缓冲区大小来推算MIB_TCPTABLE里的MIB_TCPROW数组长度 77 //下面用缓冲长度-sizeof(int)也就是去掉MIB_TCPTABLE里的成员dwNumEntries所占用的内存字节数 78 int aryTcpRowLength = (int)Math.Ceiling((double)(iBufferSize - sizeof(int)) / iTcpRowLen); 79 //重新取得TcpTable的数据 80 GetTcpTable(hTcpTableData, ref iBufferSize, false); 81 //下面是关键,由于MIB_TCPTABLE里的成员有一个是数组,而这个数组长度起初我们是不能确定的 82 //所以这里我们只能根据分配的指针来进行一些运算来推算出我们所要的数据 83 for (int i = 0; i < aryTcpRowLength; i++) 84 { 85 //hTcpTableData是指向MIB_TCPTABLE缓冲区的内存起始区域,由于其成员数据在内存中是顺序排列 86 //所以我们可以推断hTcpTableData+4(也就是sizeof(dwNumEntries)的长度)后就是MIB_TCPROW数组的第一个元素 87 IntPtr hTempTableRow = new IntPtr(hTcpTableData.ToInt32() + 4 + i * iTcpRowLen); 88 MIB_TCPROW tcpRow = new MIB_TCPROW(); 89 tcpRow.dwLocalAddr = 0; 90 tcpRow.dwLocalPort = 0; 91 tcpRow.dwRemoteAddr = 0; 92 tcpRow.dwRemotePort = 0; 93 tcpRow.dwState = 0; 94 //把指针数据拷贝到我们的结构对象里。 95 Marshal.PtrToStructure(hTempTableRow, tcpRow); 96 lstTcpRows.Add(tcpRow); 97 } 98 tcpTable.dwNumEntries = lstTcpRows.Count; 99 tcpTable.table = new MIB_TCPROW[lstTcpRows.Count]; 100 lstTcpRows.CopyTo(tcpTable.table); 101 return tcpTable; 102 } 103 public static string GetIpAddress(long ipAddrs) 104 { 105 try 106 { 107 System.Net.IPAddress ipAddress = new System.Net.IPAddress(ipAddrs); 108 return ipAddress.ToString(); 109 } 110 catch { return ipAddrs.ToString(); } 111 112 } 113 public static ushort GetTcpPort(int tcpPort) 114 { 115 return ntohs((ushort)tcpPort); 116 } 117 public static bool IsPortBusy(int port) 118 { 119 MIB_TCPTABLE tcpTableData = GetTcpTableInfo(); 120 return false; 121 } 122 }
下面我再把调用的方式顺便写一下

1 private void button1_Click(object sender, EventArgs e) 2 { 3 NativeFunc.MIB_TCPTABLE tcpTableData = new NativeFunc.MIB_TCPTABLE(); 4 tcpTableData = NativeFunc.GetTcpTableInfo(); 5 for (int i = 0; i < tcpTableData.dwNumEntries; i++) 6 { 7 this.richTextBox1.AppendText(string.Format("{0}:{1}-->>{2}:{3}\n", 8 NativeFunc.GetIpAddress(tcpTableData.table[i].dwLocalAddr), 9 NativeFunc.GetTcpPort(tcpTableData.table[i].dwLocalPort).ToString(), 10 NativeFunc.GetIpAddress(tcpTableData.table[i].dwRemoteAddr), 11 NativeFunc.GetTcpPort(tcpTableData.table[i].dwRemotePort).ToString())); 12 } 13 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY