版权声明:本文为博主原创文章,转载请显著位置标明出处,未经博主允许不得用于商业目的。 https://blog.csdn.net/UruseiBest/article/details/83064244
综合前面几篇文章,最后给出全部的代码如下:
Imports System.Runtime.InteropServices
Imports System.Net
Public Class Form1
Private Const ERROR_SUCCESS As Integer = 0
Private Const MIB_TCP_STATE_CLOSED As Integer = 1
Private Const MIB_TCP_STATE_LISTEN As Integer = 2
Private Const MIB_TCP_STATE_SYN_SENT As Integer = 3
Private Const MIB_TCP_STATE_SYN_RCVD As Integer = 4
Private Const MIB_TCP_STATE_ESTAB As Integer = 5
Private Const MIB_TCP_STATE_FIN_WAIT1 As Integer = 6
Private Const MIB_TCP_STATE_FIN_WAIT2 As Integer = 7
Private Const MIB_TCP_STATE_CLOSE_WAIT As Integer = 8
Private Const MIB_TCP_STATE_CLOSING As Integer = 9
Private Const MIB_TCP_STATE_LAST_ACK As Integer = 10
Private Const MIB_TCP_STATE_TIME_WAIT As Integer = 11
Private Const MIB_TCP_STATE_DELETE_TCB As Integer = 12
Private Enum TCP_TABLE_CLASS
TCP_TABLE_BASIC_LISTENER
TCP_TABLE_BASIC_CONNECTIONS
TCP_TABLE_BASIC_ALL
TCP_TABLE_OWNER_PID_LISTENER
TCP_TABLE_OWNER_PID_CONNECTIONS
TCP_TABLE_OWNER_PID_ALL
TCP_TABLE_OWNER_MODULE_LISTENER
TCP_TABLE_OWNER_MODULE_CONNECTIONS
TCP_TABLE_OWNER_MODULE_ALL
End Enum
'获取TCP连接对象
<DllImport("iphlpapi.dll", CharSet:=CharSet.Auto, SetLastError:=True, ExactSpelling:=True)>
Private Shared Function GetExtendedTcpTable(
ByVal pTcpTable As IntPtr, '存储TCP端口连接信息表,具体结构类型根据ulAF和TableClass参数而定。
ByRef dwOutBufLen As Integer, 'pTcpTable指向的内存大小
ByVal sort As Boolean, '返回结果是否排序。
ByVal ipVersion As Integer, 'IP类型。AF_INET——IPv4; AF_INET6——IPv6。
ByVal tblClass As TCP_TABLE_CLASS, '根据ulAF,传入相应不同值,返回的pTcpTable中结构类型不同。
ByVal reserved As Integer '保留,设为0。
) As Integer
End Function
Private Enum UDP_TABLE_CLASS
UDP_TABLE_BASIC
UDP_TABLE_OWNER_PID
UDP_TABLE_OWNER_MODULE
End Enum
'获取UDP连接对象
<DllImport("iphlpapi.dll", CharSet:=CharSet.Auto, SetLastError:=True, ExactSpelling:=True)>
Private Shared Function GetExtendedUdpTable(
ByVal pUdpTable As IntPtr, 'pTcpTable(指针类型): 存储TCP端口连接信息表,具体结构类型根据ulAF和TableClass参数而定。
ByRef dwOutBufLen As Integer, 'pdwSize(传址):pTcpTable指向的内存大小,如果pdwSize比需要的空间小,函数返回一个ERROR_INSUFFICIENT_BUFFER错误,并将pdwSize 置为所需大小。
ByVal sort As Boolean, 'bOrder(布尔): 返回结果是否排序。
ByVal ipVersion As Integer, 'ulAF(整数):IP类型。AF_INET——IPv4; AF_INET6——IPv6。
ByVal tblClass As UDP_TABLE_CLASS, 'TableClass(枚举): TCP_TABLE_CLASS 。根据ulAF,传入相应不同值,返回的pTcpTable中结构类型不同。
ByVal reserved As Integer 'Reserved(保留)设为0。
) As Integer
End Function
<StructLayout(LayoutKind.Sequential)>
Structure MIB_TCPTABLE_OWNER_PID
Dim dwNumEntries As Integer
Dim table As MIB_TCPROW_OWNER_PID
End Structure
Structure MIB_TCPROW_OWNER_PID
Dim dwState As Integer
Dim dwLocalAddr As Integer
Dim dwLocalPort As Integer
Dim dwRemoteAddr As Integer
Dim dwRemotePort As Integer
Dim dwOwningPid As Integer
End Structure
'ntohs()是一个函数名,作用是将一个16位数由网络字节顺序转换为主机字节顺序
<DllImport("wsock32.dll", CharSet:=CharSet.Auto, SetLastError:=True, ExactSpelling:=True)>
Private Shared Function ntohs(
ByVal addr As Integer
) As Integer
End Function
'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
Private Function getPort(ByVal portNum As Integer) As Integer
Return ntohs(portNum)
End Function
Private Function getProInfo(ByVal Pid As Integer) As String
Try
Dim pro As Process = Process.GetProcessById(Pid)
Return pro.ProcessName
Catch ex As Exception
Return "(No)"
End Try
End Function
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
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
'获得Tcp连接的代码--by https://blog.csdn.net/UruseiBest
Private Sub btnGetTcpLink_Click(sender As Object, e As EventArgs) Handles btnGetTcpLink.Click
ListView1.Items.Clear()
Dim tcpTable As IntPtr = IntPtr.Zero
Dim outBufLen As Integer = 0
Dim AF_INET As Integer = 2
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(arrTcpRow(i).dwLocalAddr)
lstv.SubItems.Add(arrTcpRow(i).dwLocalPort)
lstv.SubItems.Add(arrTcpRow(i).dwRemoteAddr)
lstv.SubItems.Add(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
'修正后获得Tcp连接的代码--by https://blog.csdn.net/UruseiBest
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
End Class
代码中同时还给出了GetExtendedUdpTable函数,请各位读者查阅msdn,自行写一下获得Udp连接的代码。
这里不再累述。