【问题标题】:Get a random port for TCP connection获取 TCP 连接的随机端口
【发布时间】:2014-01-14 08:39:32
【问题描述】:

我有一个客户端和一个服务器应用程序。当客户端想要发送文件时,我使用的是 TCP 连接。当我使用恒定端口号进行连接时(服务器接收文件)。

我想使用随机端口,所以我尝试将端口设置为 0。

我的代码是:

bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = 0;

if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
    cout << "failed to bind with errno: "<< errno << endl;
    exit(1);
}

绑定有效,但使用端口 0 而不是预期的随机端口。

我做错了什么?

【问题讨论】:

  • Afaik,您不需要在客户端调用 bind。然后它将随机选择端口
  • 如果服务器随机选择一个端口号,您如何期望客户端知道使用哪个端口号?
  • 队长的问题很好。一种情况是 ISO 15118 标准(电动汽车与充电站的通信),当服务器(充电站)通告 TCP 连接参数时,客户端可以通过在 UDP 数据包中广播“SDP”(服务发现协议)请求来获取子网,然后服务器以 UDP 数据包的形式将参数(IP/端口)回复给客户端。

标签: c++ linux sockets tcp port


【解决方案1】:

嗯,问题解决了。我给getsocketname添加了一个电话

if (getsockname(sockfd, (struct sockaddr *)&serv_addr, &len_inet) < 0){
    cout << "failed to get hostname with errno: "<< errno << endl;
    exit(1);
}

【讨论】:

    【解决方案2】:

    bind() 不会更新您传递给它的地址结构。这是一个const 参数。如果您想知道指定零时选择了哪个端口,则必须使用getsockname().

    【讨论】:

      【解决方案3】:

      这个小 C 工具会帮助你:https://github.com/yegor256/random-tcp-port

      只需使用make 编译它,然后运行./reserve

      【讨论】:

      • 这个小 C 工具完全没有意义。绑定时只需要一个端口号为零。
      【解决方案4】:

      当你有可用的提升时,这看起来更加明显并且是可移植的:

      #include <boost/asio/io_service.hpp>
      #include <boost/asio/ip/tcp.hpp>
      
      int getFreeTCPPort(std::string ipv4)
      {
        using namespace boost::asio;
      
        io_service service;
        ip::tcp::socket socket(service);
        socket.open(ip::tcp::v4());
        socket.bind(ip::tcp::endpoint(ip::address::from_string(ipv4), 0));
        return socket.local_endpoint().port();
      }
      

      当然,它不是直接回答你的问题,但是当代码不言自明时,也许问题就没有出现。

      【讨论】:

      • 奇怪,这个问题被标记为 c++ 但除了 cout 它与 c++ 无关 - 它是这里使用的 c API。此外,它与“linux”无关,它是 Berkeley,实际上与 POSIX 套接字相关。这个答案是使用大多数 Linux 系统(至少我知道,也是嵌入式的)上可用的通用、可移植的 c++ 库来实现标题“获取 TCP 连接的随机端口”中描述的目标作为附加建议,但被否决。还有其他答案也没有直接回答这个问题,为什么这被否决了?
      猜你喜欢
      • 2020-10-07
      • 2012-02-09
      • 2015-03-18
      • 2015-10-11
      • 1970-01-01
      • 2018-01-09
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多