这是在我的另一博客发的一表文章,做了一点修改
环境:Windows+VC
最近看到BBS上有些朋友在讨论Socket的端口占用检测问题,就顺便整理一下我在这方面的经验,希望能给需要的朋友有所帮助。(可参考http://community.csdn.net/Expert/topic/5136/5136754.xml?temp=.3932154)
一般检测一个端口是否被占用的方法是看bind是否成功,但感觉上这个方法有点不合适,其实在Windows中有两个API可以获取到当前系统端口的占用情况(GetTcpTable/GetUdpTable),利用这两个函数就可检测端口占用情况。
以下分别是TCP和UDP的检测方法:
- const static STDMETHODIMP GetPortState(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 S_OK;
- }
- }
- }
- return S_FALSE;
- }
- return S_FALSE;
- }
-
-
- const static BOOL PortUsedTCP(ULONG uPort)
- {
- 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 == uPort)
- {
- return TRUE;
- }
- }
- }
- return FALSE;
- }
- return FALSE;
- }
当然,如果在较复杂系统环境下,端口占用表可能随时改变,可能存在两个以上进程使用上述方法检测到同一空闲端口,在这种情况下,就可结合Bind方法进行端口选择。
(cn_xinxin) |