一般检测一个端口是否被占用的方法是看bind是否成功,其实在Windows中有两个API可以获取到当前系统端口的占用情况(GetTcpTable/GetUdpTable),利用这两个函数就可检测端口占用情况。
但在较复杂系统环境下,端口占用表可能随时改变,可能存在两个以上进程使用上述方法检测到同一空闲端口,在这种情况下,可使用Bind方法进行端口选择。
一、通过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;
}
二、通过bind函数,判断端口是否被占用。
1、原始socket编程时,就使用bind函数判断。
  unsigned short usPort = 9090;
  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)
	{
		//端口已被占用
	}
2、使用boost asio库时,如何判断端口被占用,使用new socket或bind失败时来判断。
boost::asio::io_service ioService;
unsigned short usPort = 9090;
udp::socket * pSockUdp = NULL;
bool bSockUdpError = false;
try{
		pSockUdp = new udp::socket(ioService,udp::endpoint(udp::v4(),usPort));
		bSockUdpError = false;
	}
	catch(...)
	{
		bSockUdpError = true;
	}
//释放
	if(!bSockUdpError && pSockUdp != NULL)
	{
		delete pSockUdp;
		pSockUdp = NULL;
	}

最新文章

  1. Javascript - Promise学习笔记
  2. 面试复习(C++)之快速排序
  3. html canvas 弹球(模仿)
  4. Principal Component Analysis(PCA) algorithm summary
  5. flume ng之组件介绍
  6. 【HDOJ】1558 Segment set
  7. WCF技术剖析之六:为什么在基于ASP.NET应用寄宿(Hosting)下配置的BaseAddress无效
  8. Python Tools
  9. Chapter 2 Open Book——10
  10. Webservice优缺点总结
  11. [BZOJ2298] [HAOI2011] problem a (dp)
  12. 巨坑– 膜BWV543
  13. C#实现全局快捷键(系统热键)响应(转)
  14. Qt 拷贝内容到粘贴板 || 获取粘贴板内容
  15. Twain
  16. Django之用户认证auth模块
  17. Cannot find config.m4. Make sure that you run &#39;/usr/local/php/bin/phpize&#39; in the top level source directory of the module的 解决方法
  18. Scrapy的【SitemapSpider】的【官网示例】没有name属性
  19. C语言中的undefined behavior
  20. sphinx配置 + php

热门文章

  1. django之中间件、缓存、信号、admin内置后台
  2. java.lang.NoSuchMethodError: scala.Predef$.refArrayOps([Ljava/lang/Object;)Lscala/collection/mutable/ArrayOps;
  3. tar命令解压时如何去除目录结构及其解压到指定目录 (--strip-components N)
  4. sdut AOE网上的关键路径(spfa+前向星)
  5. WHCTF2017线上小记
  6. Learning Query and Document Similarities from Click-through Bipartite Graph with Metadata
  7. OpenCV图像增强算法实现(直方图均衡化、拉普拉斯、Log、Gamma)
  8. 20145104张家明 《Java程序设计》第一周学习总结
  9. 【图片下载-代码】java下载网络图片资源例子
  10. 【转载】make: Nothing to be done for `all&#39;. 解决方法