众所周知,为了将套接字 fd 绑定(bind)到随机空闲端口,您将 0
作为 sockaddr_in.sin_port
传递给 bind
。然而,这似乎总是从临时端口范围分配一个端口,如下面的程序 [*] 所示。
我的问题是,有没有一种[干净]的方法可以从非临时端口范围获取随机端口?
[*]
#include <fstream>
#include <iostream>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
int main(int argc, char* argv[]) {
fstream ports("/proc/sys/net/ipv4/ip_local_port_range", fstream::in);
int eMin, eMax; ports >> eMin >> eMax;
cout << "ephemeral range: [" << eMin << ", " << eMax << "]" << endl;
for (int i = 0; i < 100; ++i) {
int fd = socket(PF_INET, SOCK_STREAM, 0);
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
socklen_t addrlen = sizeof(addr);
bind(fd, (sockaddr*)(&addr), addrlen);
getsockname(fd, (sockaddr*)(&addr), &addrlen);
uint16_t port = ntohs(addr.sin_port);
bool within = (port >= eMin) && (port <= eMax);
cout << "port " << port << " " << (within ? "in" : "out") << endl;
close(fd);
}
return 0;
}
附言现在我使用的解决方法是从非临时端口范围显式传递一个随机端口号作为 sockaddr_in.sin_port
,尝试绑定(bind)到它,如果绑定(bind)操作失败则重复冲洗。但这感觉像是在模拟系统应该提供的东西。
最佳答案
Right now the workaround I'm using is to explicitly pass a random port number from non-ephemeral port range as
sockaddr_in.sin_port
, try to bind to it, rinse-repeat if bind operation failed. But this feels like emulating something the system should provide.
遗憾的是,这正是您需要做的。没有用于从一系列非临时端口中选择可用随机端口的标准或特定于平台的 API。操作系统只知道临时端口,因为该范围是其网络配置的一部分。
关于c++ - 将套接字绑定(bind)到非临时端口范围内的空闲端口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22617852/