win32 查找本地空闲端口号

使用win32api GetTcpTable 查找本地空闲端口号
思路:
先查找本地占用端口号集合,再从想要得端口集合里面排除查找。

先上官方demo:

// Need to link with Iphlpapi.lib and Ws2_32.lib
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

/* Note: could also use malloc() and free() */

int main()
{

    // Declare and initialize variables
    PMIB_TCPTABLE pTcpTable;
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    char szLocalAddr[128];
    char szRemoteAddr[128];

    struct in_addr IpAddr;

    int i;

    pTcpTable = (MIB_TCPTABLE *) MALLOC(sizeof (MIB_TCPTABLE));
    if (pTcpTable == NULL) {
        printf("Error allocating memory\n");
        return 1;
    }

    dwSize = sizeof (MIB_TCPTABLE);
// Make an initial call to GetTcpTable to get the necessary size into the dwSize variable
    if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) ==
        ERROR_INSUFFICIENT_BUFFER) {
        FREE(pTcpTable);
        pTcpTable = (MIB_TCPTABLE *) MALLOC(dwSize);
        if (pTcpTable == NULL) {
            printf("Error allocating memory\n");
            return 1;
        }
    }
// Make a second call to GetTcpTable to get the actual data we require
    if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) == NO_ERROR) {
        printf("\tNumber of entries: %d\n", (int) pTcpTable->dwNumEntries);
        for (i = 0; i < (int) pTcpTable->dwNumEntries; i++) {
            IpAddr.S_un.S_addr = (u_long) pTcpTable->table[i].dwLocalAddr;
            strcpy_s(szLocalAddr, sizeof (szLocalAddr), inet_ntoa(IpAddr));
            IpAddr.S_un.S_addr = (u_long) pTcpTable->table[i].dwRemoteAddr;
            strcpy_s(szRemoteAddr, sizeof (szRemoteAddr), inet_ntoa(IpAddr));
			//可以根据端口号得状态去筛选
            printf("\n\tTCP[%d] State: %ld - ", i,
                   pTcpTable->table[i].dwState);
            switch (pTcpTable->table[i].dwState) {
            case MIB_TCP_STATE_CLOSED:
                printf("CLOSED\n");
                break;
            case MIB_TCP_STATE_LISTEN:
                printf("LISTEN\n");
                break;
            case MIB_TCP_STATE_SYN_SENT:
                printf("SYN-SENT\n");
                break;
            case MIB_TCP_STATE_SYN_RCVD:
                printf("SYN-RECEIVED\n");
                break;
            case MIB_TCP_STATE_ESTAB:
                printf("ESTABLISHED\n");
                break;
            case MIB_TCP_STATE_FIN_WAIT1:
                printf("FIN-WAIT-1\n");
                break;
            case MIB_TCP_STATE_FIN_WAIT2:
                printf("FIN-WAIT-2 \n");
                break;
            case MIB_TCP_STATE_CLOSE_WAIT:
                printf("CLOSE-WAIT\n");
                break;
            case MIB_TCP_STATE_CLOSING:
                printf("CLOSING\n");
                break;
            case MIB_TCP_STATE_LAST_ACK:
                printf("LAST-ACK\n");
                break;
            case MIB_TCP_STATE_TIME_WAIT:
                printf("TIME-WAIT\n");
                break;
            case MIB_TCP_STATE_DELETE_TCB:
                printf("DELETE-TCB\n");
                break;
            default:
                printf("UNKNOWN dwState value\n");
                break;
            }
            printf("\tTCP[%d] Local Addr: %s\n", i, szLocalAddr);
            printf("\tTCP[%d] Local Port: %d \n", i,
                   ntohs((u_short)pTcpTable->table[i].dwLocalPort));
            printf("\tTCP[%d] Remote Addr: %s\n", i, szRemoteAddr);
            printf("\tTCP[%d] Remote Port: %d\n", i,
                   ntohs((u_short)pTcpTable->table[i].dwRemotePort));
        }
    } else {
        printf("\tGetTcpTable failed with %d\n", dwRetVal);
        FREE(pTcpTable);
        return 1;
    }

    if (pTcpTable != NULL) {
        FREE(pTcpTable);
        pTcpTable = NULL;
    }    

    return 0;    
}

获取已占用端口号集合

#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <stdio.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

std::vector<uint16_t> GetAllTcpConnectionsPort()
{
	std::vector<uint16_t> vPorts;
	DWORD size = sizeof(MIB_TCPTABLE);
	PMIB_TCPTABLE pTcpTable = (PMIB_TCPTABLE)MALLOC(sizeof(MIB_TCPTABLE));
	if (pTcpTable == NULL) {
		std::cout << "Error allocating memory" << std::endl;
		return vPorts;
	}
	DWORD dwRetVal = 0;
	// Make an initial call to GetTcpTable to get the necessary size into the dwSize variable
	if ((dwRetVal = GetTcpTable(pTcpTable, &size, TRUE)) == ERROR_INSUFFICIENT_BUFFER) {
		FREE(pTcpTable);
		pTcpTable = nullptr;
		pTcpTable = (PMIB_TCPTABLE)MALLOC(size);
		if (pTcpTable == NULL) {
			std::cout << "Error allocating memory" << std::endl;
			return vPorts;
		}
	}
	// Make a second call to GetTcpTable to get the actual data we require
	char szLocalAddr[128] = { 0 };
	char szRemoteAddr[128] = { 0 };
	struct in_addr IpAddr, remoteAddr;
	if ((dwRetVal = GetTcpTable(pTcpTable, &size, TRUE)) == NO_ERROR) {
		std::cout << "\tNumber of entries: " << pTcpTable->dwNumEntries << std::endl;
		for (int i = 0; i < (int)pTcpTable->dwNumEntries; i++) {
			vPorts.push_back(ntohs(u_short(pTcpTable->table[i].dwLocalPort)));
			vPorts.push_back(ntohs(u_short(pTcpTable->table[i].dwRemotePort)));
#if 0
			uint16_t localPort = ntohs(u_short(pTcpTable->table[i].dwLocalPort));
			uint16_t remotePort = ntohs(u_short(pTcpTable->table[i].dwRemotePort));
			IpAddr.S_un.S_addr = (u_long)pTcpTable->table[i].dwLocalAddr;
			strcpy_s(szLocalAddr, sizeof(szLocalAddr), inet_ntoa(IpAddr));
			std::cout << "\tTCP[" << i << "]" << " Local Addr: " << std::string(szLocalAddr) << ":" << localPort << std::endl;
			remoteAddr.S_un.S_addr = (u_long)pTcpTable->table[i].dwRemoteAddr;
			strcpy_s(szRemoteAddr, sizeof(szRemoteAddr), inet_ntoa(remoteAddr));
			std::cout << "\tTCP[" << i << "]" << " Remote Addr: " << szRemoteAddr << ":" << remotePort << std::endl;
#endif
		}
	}
	else {
		std::cout << "\tGetTcpTable failed with " << dwRetVal;
		FREE(pTcpTable);
		pTcpTable = nullptr;
		return vPorts;
	}
	std::sort(vPorts.begin(), vPorts.end());
	vPorts.erase(std::unique(vPorts.begin(), vPorts.end()), vPorts.end());
	if (pTcpTable) {
		FREE(pTcpTable);
		pTcpTable = NULL;
	}
	return vPorts;
}

查找可用得端口号

uint16_t FindAvailableTcpPort(uint16_t begin /*= 10011*/, uint16_t end /*= 65535*/)
{
	auto vec = GetAllTcpConnectionsPort();
	for (uint16_t port = begin; port != end; ++port)
		if (!std::binary_search(std::begin(vec), std::end(vec), port))
			return port;
	return 0;
}

莫名得异常

当总是在奇奇怪怪得地方出现错误,比如输出异常,vector入栈异常,或者其他地方出现偶先异常,并且提示系统库内存异常中断,先排除代码使用内存问题(数组长度不够,野指针,未初始化数据,重复析构等),然后一定要看调用系统api是不是给错了参数导致内存分配不够,然后产生一系列得内存访问权限错误等。

0xC0000005: 这是一个特定的异常代码,通常与内存访问违规有关。在Windows中,这个错误代码通常表示“访问冲突”,也就是程序试图访问一个它没有权限访问的内存地址。

	if ((dwRetVal = GetTcpTable(pTcpTable, &size, TRUE)) == ERROR_INSUFFICIENT_BUFFER) {
		FREE(pTcpTable);
		pTcpTable = nullptr;
		//pTcpTable = (PMIB_TCPTABLE)MALLOC(sizeof(MIB_TCPTABLE)); //错误分配导致后面内存错误
		//第一次调用提示内存分配空间不足错误,这次要分配函数返回得足额空间大小,也就是size
		pTcpTable = (PMIB_TCPTABLE)MALLOC(size); //正确
			if (pTcpTable == NULL) {
		std::cout << "Error allocating memory" << std::endl;
		return vPorts;
	  }
   }

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值