GetExtendedTcpTable でソケットのプロセスIDを調べる
Windowsで netstat -ano のような、ソケット一覧にプロセスIDがついたものを出力するコード。
GetTcpTable() ではプロセスIDが出ないしAllocateAndGetTcpExTableFromStackはdeprecatedで、GetExtendedTcpTable はXP SP2とVistaで使える。はず。
using System; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Runtime.InteropServices; namespace readTCPTable { public class ByteParser { byte[] buf;uint size;int next; public ByteParser(byte[] b,uint s) {buf=b;size=s;next=0;} public uint readUI32() {uint r = BitConverter.ToUInt32(buf,next);next += 4;return r;} // ネットワークバイトオーダの16ビット値 public uint readNUI16() {uint r = (((uint)buf[next])<<8)|((uint)buf[next+1]);next +=2;return r;} }; public class TCPTableReader { public 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 }; public enum TCPState : uint {None = 0, CLOSED, LISTEN, SYN_SENT, SYN_RCVD, ESTABLISHED, FIN_WAIT1, FIN_WAIT2, CLOSE_WAIT, CLOSING,LAST_ACK, TIME_WAIT,DELETE_TCB, }; [DllImport("iphlpapi.dll",SetLastError=true)] public static extern int GetExtendedTcpTable( byte[] pTcpTable, out uint dwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, int reserved ); public static string stringIPv4(uint v) { byte[] ip=BitConverter.GetBytes(v); return String.Format("{0}.{1}.{2}.{3}",ip[0],ip[1],ip[2],ip[3]); } public const int AF_INET = 2; // IP_v4 public const int NO_ERROR = 0; public static bool readTCPTable(){ // バッファサイズ調査を兼ねて2回呼ぶ uint buffer_size = 1; byte[] buffer = new byte[buffer_size]; int AF_INET = 2; // IP_v4 if( NO_ERROR != GetExtendedTcpTable( buffer,out buffer_size, // 出力バッファとそのサイズ true, // TCP endpoints を降順ソートするなら真 AF_INET, // IPv4 or IPv6 TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, // one of the values from the TCP_TABLE_CLASS enumeration 0 // Reserved )){ buffer = new byte[buffer_size]; if( NO_ERROR != GetExtendedTcpTable( buffer,out buffer_size, // 出力バッファとそのサイズ true, // TCP endpoints を降順ソートするなら真 AF_INET, // IPv4 or IPv6 TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL, // one of the values from the TCP_TABLE_CLASS enumeration 0 // Reserved )){ return false; } } ByteParser bp = new ByteParser(buffer,buffer_size); uint nRows = bp.readUI32(); for(int i=0;i<nRows;++i){ TCPState state = (TCPState)bp.readUI32(); uint local_addr = bp.readUI32(); uint local_port = bp.readNUI16();bp.readNUI16(); uint remote_addr = bp.readUI32(); uint remote_port = bp.readNUI16();bp.readNUI16(); uint pid = bp.readUI32(); if(remote_addr==0) remote_port=0; Debug.WriteLine(String.Format("{1}#{2} {3}#{4} {5} {0}" ,state ,stringIPv4(local_addr),local_port ,stringIPv4(remote_addr),remote_port ,pid )); } return true; } // エントリポイント static void Main(string[] args) { readTCPTable(); } } }