• 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 }
    View Code

    下面我再把调用的方式顺便写一下

     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 }
    View Code
  • 相关阅读:
    PageAdmin Cms系统如何修改点击数(浏览数)
    最简js深浅拷贝说明
    实用的前端网址
    js的一些编码问题
    自己写一个文字过长显示省略号的函数
    垂直居中 和 水平居中
    js原码工具集
    url 、src 、href 的区别
    transform对定位元素的影响
    css实现一色多变化
  • 原文地址:https://www.cnblogs.com/yulinlover/p/1911862.html
Copyright © 2020-2023  润新知