VC++获取系统TCPUDP端口使用信息,并判断端口是否被占用(附源码)
Posted dvlinker
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++获取系统TCPUDP端口使用信息,并判断端口是否被占用(附源码)相关的知识,希望对你有一定的参考价值。
有时候我们需要判断某端口有没有被系统或者其他占用,代码该如何实现呢?其实很简单,我们可以调用系统API函数GetExtendedTcpTable和GetExtendedUdpTable,分别获取TCP和UDP端口信息,其中的信息包括与端口关联的本端IP和远端IP,占用该端口的进程id等,对应的结构体如下所示:
typedef struct _MIB_TCPROW_OWNER_MODULE
DWORD dwState;
DWORD dwLocalAddr;
DWORD dwLocalPort;
DWORD dwRemoteAddr;
DWORD dwRemotePort;
DWORD dwOwningPid;
LARGE_INTEGER liCreateTimestamp;
ULONGLONG OwningModuleInfo[TCPIP_OWNING_MODULE_SIZE];
MIB_TCPROW_OWNER_MODULE, *PMIB_TCPROW_OWNER_MODULE;
光有进程id,无法直观地看到端口被哪个程序占用了,当然我们可以通过进程id到任务管理器中去查找。通过进程的id,我们可以获取系统进程快照,得到对应的进程名称,代码如下:
BOOL GetProcessNameById( u32 ProcessId,TCHAR ProcessName[MAX_PATH] )
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
// 快照系统所有进程
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );// 第二个参数无效
if( hProcessSnap == INVALID_HANDLE_VALUE )
return FALSE;
// 结构体大小一定要填充。
pe32.dwSize = sizeof( PROCESSENTRY32 );
// 获取第一个进程信息
if( !Process32First( hProcessSnap, &pe32 ) )
CloseHandle( hProcessSnap ); // clean the snapshot object
return FALSE;
// 遍历所有进程
do
if( pe32.th32ProcessID==ProcessId )
lstrcpy( ProcessName, pe32.szExeFile );
CloseHandle(hProcessSnap );
return TRUE;
while( Process32Next( hProcessSnap, &pe32 ) );
CloseHandle(hProcessSnap );
return FALSE;
判断端口是否被占用的接口CheckPortUsed封装如下:(代码中还保存了端口的详细信息)
// 端口的详细信息
typedef struct tagTNetInfo
emPortType bySockType; // TCP、UDP
DWORD dwLocalIP; // 网络序
DWORD dwRemoteIP; // 网络序
DWORD dwLocalPort; // 网络序
DWORD dwRemotePort; // 网络序
DWORD dwPID;
TCHAR szProcessName[MAX_PATH];
TNetInfo;
BOOL CheckPortUsed( int nPort )
// 1、获取TCP连接及端口信息
// 第一次调用时不知道要传入的缓冲区大小,所以要试探一下,参数dwTcpCount会返回实际大小
PMIB_TCPTABLE_OWNER_MODULE pTCPExTable = new MIB_TCPTABLE_OWNER_MODULE;
DWORD dwTcpCount = sizeof(MIB_UDPTABLE_OWNER_MODULE);
if ( GetExtendedTcpTable( pTCPExTable, &dwTcpCount, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 ) == ERROR_INSUFFICIENT_BUFFER )
pTCPExTable = (MIB_TCPTABLE_OWNER_MODULE *)new char[dwTcpCount];
DWORD dwRet= GetExtendedTcpTable( pTCPExTable, &dwTcpCount, TRUE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0 );
if( dwRet )
return ;
// 1、获取UDP连接及端口信息
PMIB_UDPTABLE_OWNER_MODULE pUDPExTable = new MIB_UDPTABLE_OWNER_MODULE;
DWORD dwUdpCount = sizeof(MIB_TCPTABLE_OWNER_MODULE);
if ( GetExtendedUdpTable( pUDPExTable, &dwUdpCount, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 ) == ERROR_INSUFFICIENT_BUFFER )
pUDPExTable = (MIB_UDPTABLE_OWNER_MODULE *)new char[dwUdpCount];
dwRet = GetExtendedUdpTable( pUDPExTable, &dwUdpCount, TRUE, AF_INET, UDP_TABLE_OWNER_MODULE, 0 );
if( dwRet )
return ;
TCHAR szProcessName[MAX_PATH] = 0;
vector<TNetInfo*> vtPortInfoList;
// 获取TCP连接表
TNetInfo *ptNetInfo;
for( s32 i=0 ; i<pTCPExTable->dwNumEntries ; i++ )
ptNetInfo = new TNetInfo;
// 通过进程id获取进程名
GetProcessNameById( hProcessSnap, pTCPExTable->table[i].dwOwningPid, szProcessName );
ptNetInfo->bySockType = emTCP;
ptNetInfo->dwLocalIP = pTCPExTable->table[i].dwLocalAddr;
ptNetInfo->dwLocalPort = htons( pTCPExTable->table[i].dwLocalPort );
ptNetInfo->dwRemoteIP = pTCPExTable->table[i].dwRemoteAddr;
ptNetInfo->dwRemotePort= htons( pTCPExTable->table[i].dwRemotePort );
ptNetInfo->dwPID = pTCPExTable->table[i].dwOwningPid;
lstrcpy(ptNetInfo->szProcessName, szProcessName);
vtPortInfoList.push_back( ptNetInfo );
// 获取UDP连接表
for( s32 i = 0; i < pUDPExTable->dwNumEntries; i++ )
ptNetInfo = new TNetInfo;
//PID转换为进程名
GetProcessNameById( pUDPExTable->table[i].dwOwningPid, szProcessName );
ptNetInfo->bySockType = emUDP;
ptNetInfo->dwLocalIP = pUDPExTable->table[i].dwLocalAddr;
ptNetInfo->dwLocalPort = htons( pUDPExTable->table[i].dwLocalPort );
ptNetInfo->dwPID = pUDPExTable->table[i].dwOwningPid;
ptNetInfo->szProcessName = szProcessName;
vtPortInfoList.push_back( ptNetInfo );
DWORD dwNetPort = ntohl( nPort );
for ( int i = 0; i < vtPortInfoList.size(); i++ )
if ( dwNetPort == vtPortInfoList[i].dwLocalPort )
return TRUE;
return FALSE;
以上是关于VC++获取系统TCPUDP端口使用信息,并判断端口是否被占用(附源码)的主要内容,如果未能解决你的问题,请参考以下文章