C++检测网络端口是否被占用
最近在使用Nginx搭建Web服务器,Nginx(发音同 engine x)是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个 BSD-like 协议下发行,可以在 UNIX、GNU/Linux、BSD、Mac OS X、Solaris,以及 Microsoft Windows 等操作系统中运行。将nginx设置成服务并开机自启动,在配置文件中需要写入端口号,但是系统中的端口号存在被占用的情况,需要对端口号进行检测,大体思路就是检测8080端口是否被占用,如果被占用了端口号+1,如果仍被占用再+1。
方法一:通过GetTcpTable/GetUdpTable方法判断端口是否被占用
#include <tcpmib.h>
#include <IPHlpApi.h>
//依赖lib库 Iphlpapi.lib Ws2_32.lib
//获取Tcp端口状态
BOOL GetTcpPortState(ULONG nPort, ULONG *nStateID)
{
MIB_TCPTABLE TcpTable[100];
DWORD nSize = sizeof(TcpTable);
if(NO_ERROR == GetTcpTable(&TcpTable[0],&nSize,TRUE))
{
DWORD nCount = TcpTable[0].dwNumEntries;
if (nCount > 0)
{
for(DWORD i=0;i<nCount;i++)
{
MIB_TCPROW TcpRow = TcpTable[0].table[i];
DWORD temp1 = TcpRow.dwLocalPort;
int temp2 = temp1 / 256 + (temp1 % 256) * 256;
if(temp2 == nPort)
{
*nStateID = TcpRow.dwState;
return TRUE;
}
}
}
return FALSE;
}
return FALSE;
}
//获取Udp端口状态
BOOL GetUdpPortState(ULONG nPort, ULONG *nStateID)
{
MIB_UDPTABLE UdpTable[100];
DWORD nSize = sizeof(UdpTable);
if(NO_ERROR == GetUdpTable(&UdpTable[0],&nSize,TRUE))
{
DWORD nCount = UdpTable[0].dwNumEntries;
if (nCount > 0)
{
for(DWORD i=0;i<nCount;i++)
{
MIB_UDPROW TcpRow = UdpTable[0].table[i];
DWORD temp1 = TcpRow.dwLocalPort;
int temp2 = temp1 / 256 + (temp1 % 256) * 256;
if(temp2 == nPort)
{
return TRUE;
}
}
}
return FALSE;
}
return FALSE;
}
方法二:通过socket绑定的方法判断端口是否被占用
BOOL GetSocketPortState(ULONG nPort)
{
unsigned short usPort = (unsigned short)nPort;
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(usPort);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(s, (LPSOCKADDR)&addr, sizeof(addr));
if (WSAGetLastError() == WSAEADDRINUSE)
{
//端口已被占用
return TRUE;
}
else
{
return FALSE;
}
}