c++ - 将套接字绑定(bind)到非临时端口范围内的空闲端口

标签 c++ linux sockets

众所周知,为了将套接字 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/

相关文章:

python - 如何创建一个监听文件描述符的 Python 套接字服务器?

c++ - `const` 对象的构造函数

c++ - 一个类可以在同一个命名空间中拥有另一个同名的成员吗?

c++ - freopen : reverting back to original stream

C++ 为有限数量设置的所有变体编译代码

python - 在 Linux 上调度 Python 脚本

android - 当我输入 ionic cordova build android

sockets - Groovy套接字编程和IP地址

java - 在 Linux 中作为服务安装的 Spring-Boot 应用程序无法共享 postgresql 数据库

Java、Socket 和传输文本