C#如何使用GetTcpTable API获取TCP/IP连接信息
2013-03-01 12:13
302 查看
来自:http://blog.csdn.net/yulinlover/article/details/3868824
C#中如何使用GetTcpTable API函数来取得本机的连接信息
代码已经加了详细注释,我想有需要的同志一定会看得明白了
下面我再把调用的方式顺便写一下
C#中如何使用GetTcpTable API函数来取得本机的连接信息
代码已经加了详细注释,我想有需要的同志一定会看得明白了
public class NativeFunc { [StructLayout(LayoutKind.Sequential)] public class MIB_TCPROW { public int dwState; public int dwLocalAddr; public int dwLocalPort; public int dwRemoteAddr; public int dwRemotePort; } [StructLayout(LayoutKind.Sequential)] public class MIB_TCPTABLE { public int dwNumEntries; public MIB_TCPROW[] table; } [DllImport("Iphlpapi.dll")] static extern int GetTcpTable(IntPtr pTcpTable, ref int pdwSize, bool bOrder); [DllImport("Iphlpapi.dll")] static extern int SendARP(Int32 DestIP, Int32 SrcIP, ref Int64 MacAddr, ref Int32 PhyAddrLen); [DllImport("Ws2_32.dll")] static extern Int32 inet_addr(string ipaddr); [DllImport("Ws2_32.dll")] static extern ushort ntohs(ushort netshort); //SendArp获取MAC地址 public static string GetMacAddress(string macip) { StringBuilder strReturn = new StringBuilder(); try { Int32 remote = inet_addr(macip); Int64 macinfo = new Int64(); Int32 length = 6; SendARP(remote, 0, ref macinfo, ref length); string temp = System.Convert.ToString(macinfo, 16).PadLeft(12, '0').ToUpper(); int x = 12; for (int i = 0; i < 6; i++) { if (i == 5) { strReturn.Append(temp.Substring(x - 2, 2)); } else { strReturn.Append(temp.Substring(x - 2, 2) + ":"); } x -= 2; } return strReturn.ToString(); } catch { return string.Empty; } } public static bool IsHostAlive(string strHostIP) { string strHostMac = GetMacAddress(strHostIP); return !string.IsNullOrEmpty(strHostMac); } public static MIB_TCPTABLE GetTcpTableInfo() { //声明一个指针准备接受Tcp连接信息 IntPtr hTcpTableData = IntPtr.Zero; //声明hTcpTableData指针所指向的内存缓冲区大小 int iBufferSize = 0; //声明MIB_TCPTABLE对象,作为返回值 MIB_TCPTABLE tcpTable = new MIB_TCPTABLE(); //声明一个List对象来临时存放MIB_TCPROW对象 List<MIB_TCPROW> lstTcpRows = new List<MIB_TCPROW>(); //调用API来获得真正的缓冲区大小,iBufferSize默认为0, //这时调用API GetTcpTable会触发一个异常ERROR_INSUFFICIENT_BUFFER //通过这个异常系统会把真正的缓冲长度返回 GetTcpTable(hTcpTableData, ref iBufferSize, false); //为托管指针在堆上分配内存 hTcpTableData = Marshal.AllocHGlobal(iBufferSize); //求得MIB_TCPROW对象的内存字节数 int iTcpRowLen = Marshal.SizeOf(typeof(MIB_TCPROW)); //根据上面得到的缓冲区大小来推算MIB_TCPTABLE里的MIB_TCPROW数组长度 //下面用缓冲长度-sizeof(int)也就是去掉MIB_TCPTABLE里的成员dwNumEntries所占用的内存字节数 int aryTcpRowLength = (int)Math.Ceiling((double)(iBufferSize - sizeof(int)) / iTcpRowLen); //重新取得TcpTable的数据 GetTcpTable(hTcpTableData, ref iBufferSize, false); //下面是关键,由于MIB_TCPTABLE里的成员有一个是数组,而这个数组长度起初我们是不能确定的 //所以这里我们只能根据分配的指针来进行一些运算来推算出我们所要的数据 for (int i = 0; i < aryTcpRowLength; i++) { //hTcpTableData是指向MIB_TCPTABLE缓冲区的内存起始区域,由于其成员数据在内存中是顺序排列 //所以我们可以推断hTcpTableData+4(也就是sizeof(dwNumEntries)的长度)后就是MIB_TCPROW数组的第一个元素 IntPtr hTempTableRow = new IntPtr(hTcpTableData.ToInt32() + 4 + i * iTcpRowLen); MIB_TCPROW tcpRow = new MIB_TCPROW(); tcpRow.dwLocalAddr = 0; tcpRow.dwLocalPort = 0; tcpRow.dwRemoteAddr = 0; tcpRow.dwRemotePort = 0; tcpRow.dwState = 0; //把指针数据拷贝到我们的结构对象里。 Marshal.PtrToStructure(hTempTableRow, tcpRow); lstTcpRows.Add(tcpRow); } tcpTable.dwNumEntries = lstTcpRows.Count; tcpTable.table = new MIB_TCPROW[lstTcpRows.Count]; lstTcpRows.CopyTo(tcpTable.table); return tcpTable; } public static string GetIpAddress(long ipAddrs) { try { System.Net.IPAddress ipAddress = new System.Net.IPAddress(ipAddrs); return ipAddress.ToString(); } catch { return ipAddrs.ToString(); } } public static ushort GetTcpPort(int tcpPort) { return ntohs((ushort)tcpPort); } public static bool IsPortBusy(int port) { MIB_TCPTABLE tcpTableData = GetTcpTableInfo(); return false; } }
下面我再把调用的方式顺便写一下
private void button1_Click(object sender, EventArgs e) { NativeFunc.MIB_TCPTABLE tcpTableData = new NativeFunc.MIB_TCPTABLE(); tcpTableData = NativeFunc.GetTcpTableInfo(); for (int i = 0; i < tcpTableData.dwNumEntries; i++) { this.richTextBox1.AppendText(string.Format("{0}:{1}-->>{2}:{3}/n", NativeFunc.GetIpAddress(tcpTableData.table[i].dwLocalAddr), NativeFunc.GetTcpPort(tcpTableData.table[i].dwLocalPort).ToString(), NativeFunc.GetIpAddress(tcpTableData.table[i].dwRemoteAddr), NativeFunc.GetTcpPort(tcpTableData.table[i].dwRemotePort).ToString())); } }
相关文章推荐
- C#如何使用GetTcpTable API获取TCP/IP连接信息
- 在vb中使用Iphlpapi.dll获取网络信息 第二章 第四节 获取当前TCP连接情况
- 在vb中使用Iphlpapi.dll获取网络信息 第二章 第十七节 设置TCP连接状态
- 使用ACE_SOCK_SEQPACK_Association获取socket连接的本地及远程IP端口信息
- 在vb中使用Iphlpapi.dll获取网络信息 第二章 第四节 获取当前TCP连接情况
- 在vb中使用Iphlpapi.dll获取网络信息 第二章 第十七节 设置TCP连接状态
- 使用nginx后如何在web应用中获取用户ip及原理解释
- jsp,使用jdbc连接数据库出现“到主机的TCP/ip连接失败”的解决办法
- 使用nginx后如何在web应用中获取用户ip及原理解释
- 使用Nginx后如何在web应用中获取用户ip及原理解释
- C winpcap 网络抓包 并获取IP TCP 协议的相关信息
- 转一个文章:一直在使用的协议但是有些糊涂的(TCP/IP,http,socket,长连接,短连接)
- DataSnap Server端获取Client 连接信息 IP 等
- 使用Java的TCP/Ip创建本地测试连接
- javascript开发中如何使用face++,得到人脸数据(如何简单获取图片url,如何获取完整的人脸信息)
- wireshark的使用教程--用实践的方式帮助我们理解TCP/IP中的各个协议是如何工作的
- 如何解决 Windows XP 的 TCP/IP 连接问题
- 显示协议统计信息和当前 TCP/IP 网络连接
- 使用ZLG TCP/IP建立多个UDP连接的注意事项
- 如何利用Java获取系统的信息(CPU、内存、各盘符使用情况)