您的位置:首页 > 理论基础

获取计算机占用端口的信息及进程

2017-10-26 20:09 531 查看
背景:没什么说的,上代码

方法一(调用windowsApi):

using ICT.NetHandleLibrary;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;

namespace ICT.NetHandleLibrary
{
public class IPv4Post
{
static Logger<IPv4Post> log = new Logger<IPv4Post>();

// The version of IP used by the TCP/UDP endpoint. AF_INET is used for IPv4.
private const int AF_INET = 2;
// List of Active TCP Connections.
public static List<TcpProcessRecord> TcpActiveConnections = null;
// List of Active UDP Connections.
public static List<UdpProcessRecord> UdpActiveConnections = null;

// The GetExtendedTcpTable function retrieves a table that contains a list of GetExtendedTcpTable
// TCP endpoints available to the application. Decorating the function with
// DllImport attribute indicates that the attributed method is exposed by an DllImport
// unmanaged dynamic-link library 'iphlpapi.dll' as a static entry point.
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int pdwSize,
bool bOrder, int ulAf, TcpTableClass tableClass, uint reserved = 0);

// The GetExtendedUdpTable function retrieves a table that contains a list of
// UDP endpoints available to the application. Decorating the function with
// DllImport attribute indicates that the attributed method is exposed by an
// unmanaged dynamic-link library 'iphlpapi.dll' as a static entry point.
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int pdwSize,
bool bOrder, int ulAf, UdpTableClass tableClass, uint reserved = 0);

/// <summary>
/// This function reads and parses the active TCP socket connections available
/// and stores them in a list.
/// </summary>
/// <returns>
/// It returns the current set of TCP socket connections which are active.
/// </returns>
/// <exception cref="OutOfMemoryException">
/// This exception may be thrown by the function Marshal.AllocHGlobal when there
/// is insufficient memory to satisfy the request.
/// </exception>
public static List<TcpProcessRecord> GetAllTcpConnections()
{
int bufferSize = 0;
List<TcpProcessRecord> tcpTableRecords = new List<TcpProcessRecord>();

// Getting the size of TCP table, that is returned in 'bufferSize' variable.
uint result = GetExtendedTcpTable(IntPtr.Zero, ref bufferSize, true, AF_INET,
TcpTableClass.TCP_TABLE_OWNER_PID_ALL);

// Allocating memory from the unmanaged memory of the process by using the
// specified number of bytes in 'bufferSize' variable.
IntPtr tcpTableRecordsPtr = Marshal.AllocHGlobal(bufferSize);

try
{
// The size of the table returned in 'bufferSize' variable in previous
// call must be used in this subsequent call to 'GetExtendedTcpTable'
// function in order to successfully retrieve the table.
result = GetExtendedTcpTable(tcpTableRecordsPtr, ref bufferSize, true,
AF_INET, TcpTableClass.TCP_TABLE_OWNER_PID_ALL);

// Non-zero value represent the function 'GetExtendedTcpTable' failed,
// hence empty list is returned to the caller function.
if (result != 0)
return new List<TcpProcessRecord>();

// Marshals data from an unmanaged block of memory to a newly allocated
// managed object 'tcpRecordsTable' of type 'MIB_T
4000
CPTABLE_OWNER_PID'
// to get number of entries of the specified TCP table structure.
MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID)
Marshal.PtrToStructure(tcpTableRecordsPtr,
typeof(MIB_TCPTABLE_OWNER_PID));
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr +
Marshal.SizeOf(tcpRecordsTable.dwNumEntries));

// Reading and parsing the TCP records one by one from the table and
// storing them in a list of 'TcpProcessRecord' structure type objects.
for (int row = 0; row < tcpRecordsTable.dwNumEntries; row++)
{
MIB_TCPROW_OWNER_PID tcpRow = (MIB_TCPROW_OWNER_PID)Marshal.
PtrToStructure(tableRowPtr, typeof(MIB_TCPROW_OWNER_PID));
tcpTableRecords.Add(new TcpProcessRecord(
new IPAddress(tcpRow.localAddr),
new IPAddress(tcpRow.remoteAddr),
BitConverter.ToUInt16(new byte[2] {
tcpRow.localPort[1],
tcpRow.localPort[0] }, 0),
BitConverter.ToUInt16(new byte[2] {
tcpRow.remotePort[1],
tcpRow.remotePort[0] }, 0),
tcpRow.owningPid, tcpRow.state));
tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(tcpRow));
}
}
catch (OutOfMemoryException outOfMemoryException)
{
log.Error(outOfMemoryException.Message);

}
catch (Exception exception)
{
log.Error(exception.Message);
}
finally
{
Marshal.FreeHGlobal(tcpTableRecordsPtr);
}
return tcpTableRecords != null ? tcpTableRecords.Distinct()
.ToList<TcpProcessRecord>() : new List<TcpProcessRecord>();
}

/// <summary>
/// This function reads and parses the active UDP socket connections available
/// and stores them in a list.
/// </summary>
/// <returns>
/// It returns the current set of UDP socket connections which are active.
/// </returns>
/// <exception cref="OutOfMemoryException">
/// This exception may be thrown by the function Marshal.AllocHGlobal when there
/// is insufficient memory to satisfy the request.
/// </exception>
public static List<UdpProcessRecord> GetAllUdpConnections()
{
int bufferSize = 0;
List<UdpProcessRecord> udpTableRecords = new List<UdpProcessRecord>();

// Getting the size of UDP table, that is returned in 'bufferSize' variable.
uint result = GetExtendedUdpTable(IntPtr.Zero, ref bufferSize, true,
AF_INET, UdpTableClass.UDP_TABLE_OWNER_PID);

// Allocating memory from the unmanaged memory of the process by using the
// specified number of bytes in 'bufferSize' variable.
IntPtr udpTableRecordPtr = Marshal.AllocHGlobal(bufferSize);

try
{
// The size of the table returned in 'bufferSize' variable in previous
// call must be used in this subsequent call to 'GetExtendedUdpTable'
// function in order to successfully retrieve the table.
result = GetExtendedUdpTable(udpTableRecordPtr, ref bufferSize, true,
AF_INET, UdpTableClass.UDP_TABLE_OWNER_PID);

// Non-zero value represent the function 'GetExtendedUdpTable' failed,
// hence empty list is returned to the caller function.
if (result != 0)
return new List<UdpProcessRecord>();

// Marshals data from an unmanaged block of memory to a newly allocated
// managed object 'udpRecordsTable' of type 'MIB_UDPTABLE_OWNER_PID'
// to get number of entries of the specified TCP table structure.
MIB_UDPTABLE_OWNER_PID udpRecordsTable = (MIB_UDPTABLE_OWNER_PID)
Marshal.PtrToStructure(udpTableRecordPtr, typeof(MIB_UDPTABLE_OWNER_PID));
IntPtr tableRowPtr = (IntPtr)((long)udpTableRecordPtr +
Marshal.SizeOf(udpRecordsTable.dwNumEntries));

// Reading and parsing the UDP records one by one from the table and
// storing them in a list of 'UdpProcessRecord' structure type objects.
for (int i = 0; i < udpRecordsTable.dwNumEntries; i++)
{
MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID)
Marshal.PtrToStructure(tableRowPtr, typeof(MIB_UDPROW_OWNER_PID));
udpTableRecords.Add(new UdpProcessRecord(new IPAddress(udpRow.localAddr),
BitConverter.ToUInt16(new byte[2] { udpRow.localPort[1],
udpRow.localPort[0] }, 0), udpRow.owningPid));
tableRowPtr = (IntPtr)((long)tableRowPtr + Marshal.SizeOf(udpRow));
}
}
catch (OutOfMemoryException outOfMemoryException)
{
log.Error(outOfMemoryException.Message);
}
catch (Exception exception)
{
log.Error(exception.Message);
}
finally
{
Marshal.FreeHGlobal(udpTableRecordPtr);
}
return udpTableRecords != null ? udpTableRecords.Distinct()
.ToList<UdpProcessRecord>() : new List<UdpProcessRecord>();
}
}

// Enum for protocol types.
public enum Protocol
{
TCP,
UDP
}

// Enum to define the set of values used to indicate the type of table returned by
// calls made to the function 'GetExtendedTcpTable'.
public enum TcpTableClass
{
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
}

// Enum to define the set of values used to indicate the type of table returned by calls
// made to the function GetExtendedUdpTable.
public enum UdpTableClass
{
UDP_TABLE_BASIC,
UDP_TABLE_OWNER_PID,
UDP_TABLE_OWNER_MODULE
}

// Enum for different possible states of TCP connection
public enum MibTcpState
{
CLOSED = 1,
LISTENING = 2,
SYN_SENT = 3,
SYN_RCVD = 4,
ESTABLISHED = 5,
FIN_WAIT1 = 6,
FIN_WAIT2 = 7,
CLOSE_WAIT = 8,
CLOSING = 9,
LAST_ACK = 10,
TIME_WAIT = 11,
DELETE_TCB = 12,
NONE = 0
}

/// <summary>
/// The structure contains information that describes an IPv4 TCP connection with
/// IPv4 addresses, ports used by the TCP connection, and the specific process ID
/// (PID) associated with connection.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPROW_OWNER_PID
{
public MibTcpState state;
public uint localAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
public uint remoteAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] remotePort;
public int owningPid;
}

/// <summary>
/// The structure contains a table of process IDs (PIDs) and the IPv4 TCP links that
/// are context bound to these PIDs.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPTABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,
SizeConst = 1)]
public MIB_TCPROW_OWNER_PID[] table;
}
/// <summary>
/// This class provides access an IPv4 TCP connection addresses and ports and its
/// associated Process IDs and names.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class TcpProcessRecord
{
[DisplayName("Local Address")]
public IPAddress LocalAddress { get; set; }
[DisplayName("Local Port")]
public ushort LocalPort { get; set; }
[DisplayName("Remote Address")]
public IPAddress RemoteAddress { get; set; }
[DisplayName("Remote Port")]
public ushort RemotePort { get; set; }
[DisplayName("State")]
c9f3

public MibTcpState State { get; set; }
[DisplayName("Process ID")]
public int ProcessId { get; set; }
[DisplayName("Process Name")]
public string ProcessName { get; set; }

public TcpProcessRecord(IPAddress localIp, IPAddress remoteIp, ushort localPort,
ushort remotePort, int pId, MibTcpState state)
{
LocalAddress = localIp;
RemoteAddress = remoteIp;
LocalPort = localPort;
RemotePort = remotePort;
State = state;
ProcessId = pId;
// Getting the process name associated with a process id.
if (Process.GetProcesses().Any(process => process.Id == pId))
{
ProcessName = Process.GetProcessById(ProcessId).ProcessName;
}
}
}

/// <summary>
/// The structure contains an entry from the User Datagram Protocol (UDP) listener
/// table for IPv4 on the local computer. The entry also includes the process ID
/// (PID) that issued the call to the bind function for the UDP endpoint.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDPROW_OWNER_PID
{
public uint localAddr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] localPort;
public int owningPid;
}

/// <summary>
/// The structure contains the User Datagram Protocol (UDP) listener table for IPv4
/// on the local computer. The table also includes the process ID (PID) that issued
/// the call to the bind function for each UDP endpoint.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct MIB_UDPTABLE_OWNER_PID
{
public uint dwNumEntries;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,
SizeConst = 1)]
public UdpProcessRecord[] table;
}

/// <summary>
/// This class provides access an IPv4 UDP connection addresses and ports and its
/// associated Process IDs and names.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public class UdpProcessRecord
{
[DisplayName("Local Address")]
public IPAddress LocalAddress { get; set; }
[DisplayName("Local Port")]
public uint LocalPort { get; set; }
[DisplayName("Process ID")]
public int ProcessId { get; set; }
[DisplayName("Process Name")]
public string ProcessName { get; set; }

public UdpProcessRecord(IPAddress localAddress, uint localPort, int pId)
{
LocalAddress = localAddress;
LocalPort = localPort;
ProcessId = pId;
if (Process.GetProcesses().Any(process => process.Id == pId))
ProcessName = Process.GetProcessById(ProcessId).ProcessName;
}
}
}


第二种方法(写脚本):

public static List<Port> GetNetStatPorts()
{
var Ports = new List<Port>();

try {
using (Process p = new Process()) {

ProcessStartInfo ps = new ProcessStartInfo();
ps.Arguments = "-a -n -o";
ps.FileName = "netstat.exe";
ps.UseShellExecute = false;
ps.WindowStyle = ProcessWindowStyle.Hidden;
ps.RedirectStandardInput = true;
ps.RedirectStandardOutput = true;
ps.RedirectStandardError = true;

p.StartInfo = ps;
p.Start();

StreamReader stdOutput = p.StandardOutput;
StreamReader stdError = p.StandardError;

string content = stdOutput.ReadToEnd() + stdError.ReadToEnd();
string exitStatus = p.ExitCode.ToString();

if (exitStatus != "0") {
// Command Errored. Handle Here If Need Be
}

//Get The Rows
string[] rows = Regex.Split(content, "\r\n");
foreach (string row in rows) {
//Split it baby
string[] tokens = Regex.Split(row, "\\s+");
if (tokens.Length > 4 && (tokens[1].Equals("UDP") || tokens[1].Equals("TCP"))) {
string localAddress = Regex.Replace(tokens[2], @"\[(.*?)\]", "1.1.1.1");
Ports.Add(new Port {
protocol = localAddress.Contains("1.1.1.1") ? String.Format("{0}v6",tokens[1]) : String.Format("{0}v4",tokens[1]),
port_number = localAddress.Split(':')[1],
process_name = tokens[1] == "UDP" ? LookupProcess(Convert.ToInt16(tokens[4])) : LookupProcess(Convert.ToInt16(tokens[5]))
});
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message)
}
return Ports;
}

public static string LookupProcess(int pid)
{
string procName;
try { procName = Process.GetProcessById(pid).ProcessName; }
catch (Exception) { procName = "-";}
return procName;
}

public class Port
{
public string name
{
get
{
return string.Format("{0} ({1} port {2})",this.process_name, this.protocol, this.port_number);
}
set { }
}
public string port_number { get; set; }
public string process_name { get; set; }
public string protocol { get; set; }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息