有时候我们可能需要随机获取一个可用的端口号,本文采用使用以下方法完成这项任务:
思路: 将一个socket 绑定到本机,使用getsockname获取此socket关联的端口号
我们可以定义这样一个函数,用以获取可用的端口号:
函数声明
bool getAvaliablePort(unsigned
short &port);
// 返回:若成功则为true, 否则为false
// 返回:若成功则为true, 否则为false
下面是函数定义:
1 /**
2
* @brief 获取可用的端口
3 *
4 * @param port : 输出,返回可用的端口号
5 *
6 * @return 若成功则返回true,否则放回false
7 */
8 bool getAvaliablePort(unsigned short &port)
9 {
10 bool result = true;
11
12 // 1. 创建一个socket
13 SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
14
15 // 2. 创建一个sockaddr,并将它的端口号设为0
16 struct sockaddr_in addr;
17 addr.sin_family = AF_INET;
18 addr.sin_addr.s_addr = htonl(ADDR_ANY);
19 addr.sin_port = 0; // 若port指定为0,则调用bind时,系统会为其指定一个可用的端口号
20
21 // 3. 绑定
22 int ret = bind(sock, (SOCKADDR*)&addr, sizeof addr);
23
24 if ( 0 != ret) {
25 result = false;
26 goto END;
27 }
28
29 // 4. 利用getsockname获取
30 struct sockaddr_in connAddr;
31 int len = sizeof connAddr;
32 ret = getsockname(sock, (SOCKADDR*)&connAddr, &len);
33
34 if ( 0 != ret){
35 result = false;
36 goto END;
37 }
38
39 port = ntohs(connAddr.sin_port); // 获取端口号
40
41 END:
42 if ( 0 != closesocket(sock) )
43 result = false;
44 return result;
45 }
3 *
4 * @param port : 输出,返回可用的端口号
5 *
6 * @return 若成功则返回true,否则放回false
7 */
8 bool getAvaliablePort(unsigned short &port)
9 {
10 bool result = true;
11
12 // 1. 创建一个socket
13 SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
14
15 // 2. 创建一个sockaddr,并将它的端口号设为0
16 struct sockaddr_in addr;
17 addr.sin_family = AF_INET;
18 addr.sin_addr.s_addr = htonl(ADDR_ANY);
19 addr.sin_port = 0; // 若port指定为0,则调用bind时,系统会为其指定一个可用的端口号
20
21 // 3. 绑定
22 int ret = bind(sock, (SOCKADDR*)&addr, sizeof addr);
23
24 if ( 0 != ret) {
25 result = false;
26 goto END;
27 }
28
29 // 4. 利用getsockname获取
30 struct sockaddr_in connAddr;
31 int len = sizeof connAddr;
32 ret = getsockname(sock, (SOCKADDR*)&connAddr, &len);
33
34 if ( 0 != ret){
35 result = false;
36 goto END;
37 }
38
39 port = ntohs(connAddr.sin_port); // 获取端口号
40
41 END:
42 if ( 0 != closesocket(sock) )
43 result = false;
44 return result;
45 }