版权声明:本文为博主原创文章,转载请显著位置标明出处,未经博主允许不得用于商业目的。 https://blog.csdn.net/UruseiBest/article/details/83064105
上一篇文章已经将端口和进程进行了关联,但是,还存在部分问题:
1、IP地址是一个Integer,需要转换为*.*.*.*的结构(IPv4);
2、与netstat 命令对比,你会发现,端口号不一样。
第一个问题
IP是一个四段1个字节的数据,所以合起来就是一个Integer。那么如何获得实际的Ip地址呢?
以下两个方法:
1、使用 BitConverter.GetBytes转换成字节数组:
Private Function getIPx(ByVal Addr As Integer) As String
Dim ip(3) As Byte
ip = BitConverter.GetBytes(Addr)
Return ip(0).ToString & "." & ip(1).ToString & "." & ip(2).ToString & "." & ip(3).ToString
End Function
2、使用指针转换:
Private Function getIP(ByVal Addr As Integer) As String
Dim ip(3) As Byte
Dim gc As GCHandle = GCHandle.Alloc(Addr, GCHandleType.Pinned)
Dim ptrIp As IntPtr = gc.AddrOfPinnedObject()
Marshal.Copy(ptrIp, ip, 0, 4)
Return ip(0).ToString & "." & ip(1).ToString & "." & ip(2).ToString & "." & ip(3).ToString
gc.Free()
End Function
第二个问题:
先看看msdn的说明:
'The dwLocalPort, and dwRemotePort members are in network byte order.
'In order to use the dwLocalPort Or dwRemotePort members,
'the ntohs Or inet_ntoa functions In Windows Sockets Or similar functions may be needed
也就是说获得的是网络字节顺序,详细的信息请自己百度。按照msdn的提示,我们使用ntohs或者inet_ntoa就可以获得正常的数据了。ntohs的定义如下:
<DllImport("wsock32.dll", CharSet:=CharSet.Auto, SetLastError:=True, ExactSpelling:=True)>
Private Shared Function ntohs(
ByVal addr As Integer
) As Integer
End Function
修改后的代码如下:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ListView1.Items.Clear()
Dim tcpTable As IntPtr = IntPtr.Zero
Dim outBufLen As Integer = 0
Dim AF_INET As Integer = 2
Dim AF_INET6 As Integer = 23
Dim result As Integer
result = GetExtendedTcpTable(IntPtr.Zero, outBufLen, False, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0)
If result = 0 Then Exit Sub
tcpTable = Marshal.AllocHGlobal(outBufLen)
result = GetExtendedTcpTable(tcpTable, outBufLen, False, AF_INET, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, 0)
If result <> 0 Then Exit Sub
Try
Dim mtop As MIB_TCPTABLE_OWNER_PID
mtop = CType(Marshal.PtrToStructure(tcpTable, GetType(MIB_TCPTABLE_OWNER_PID)), MIB_TCPTABLE_OWNER_PID)
Dim tablecount As Integer = mtop.dwNumEntries
Dim pMTr As IntPtr = tcpTable.ToInt32 + Marshal.SizeOf(mtop.dwNumEntries)
Dim arrTcpRow(tablecount - 1) As MIB_TCPROW_OWNER_PID
For i As Integer = 0 To tablecount - 1
Dim tcprow As MIB_TCPROW_OWNER_PID = CType(Marshal.PtrToStructure(pMTr, GetType(MIB_TCPROW_OWNER_PID)), MIB_TCPROW_OWNER_PID)
arrTcpRow(i) = tcprow
pMTr = pMTr.ToInt32 + Marshal.SizeOf(tcprow)
Next
Dim lstv As ListViewItem
For i As Integer = 0 To tablecount - 1
lstv = New ListViewItem()
lstv.Text = getProInfo(arrTcpRow(i).dwOwningPid)
lstv.SubItems.Add(arrTcpRow(i).dwOwningPid)
lstv.SubItems.Add(getIP(arrTcpRow(i).dwLocalAddr))
lstv.SubItems.Add(getPort(arrTcpRow(i).dwLocalPort))
lstv.SubItems.Add(getIP(arrTcpRow(i).dwRemoteAddr))
lstv.SubItems.Add(getPort(arrTcpRow(i).dwRemotePort))
lstv.SubItems.Add(arrTcpRow(i).dwState)
ListView1.Items.Add(lstv)
Next
Catch ex As Exception
Marshal.FreeHGlobal(tcpTable)
MessageBox.Show("获得TCP表出错")
Exit Sub
End Try
Marshal.FreeHGlobal(tcpTable)
End Sub