端口为零的绑定会将您绑定到空闲端口。这是便携的吗? [关闭]

Posted

技术标签:

【中文标题】端口为零的绑定会将您绑定到空闲端口。这是便携的吗? [关闭]【英文标题】:A bind with a port of zero will bind you to a free port. Is this portable? [closed] 【发布时间】:2011-08-19 05:45:38 【问题描述】:

我希望我的程序绑定到一个空闲端口。

Google 告诉我使用 port=0 的绑定可以做到这一点,但我还没有发现这是否可以保证在任何系统(特别是 Windows/Linux)上工作。

有人可以链接一个这样说的文档吗?

【问题讨论】:

如果你想选择临时端口,你不应该跳过 bind() 调用吗? @CodePainters - 不在接收套接字上,没有。 @Alnitak 嗯,至少在 Linux 上它按我预期的那样工作(刚刚验证) - 跳过 bind(),使用 socket()/listen()/accept() 会导致监听套接字使用临时端口。但是,我不确定 Win32。 是的,根据“TCP/IP Illustrated vol 2”,如果您不绑定自己,4.2BSD 代码似乎会隐式绑定到临时端口。 为什么不直接查看文档呢?答案是对 Windows msdn.microsoft.com/en-us/library/windows/desktop/… 【参考方案1】:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
int main()

    struct sockaddr_in addr;
    socklen_t addrLen;
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == -1) 
        printf("Failed to create socket");
    
    addr.sin_family = AF_INET;
    addr.sin_port = 0; 
    addr.sin_addr.s_addr = INADDR_ANY; 
    if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) == -1) 
        printf("Failed to bind");
    
    addrLen = sizeof(addr);
    if (getsockname(fd, (struct sockaddr *)&addr, &addrLen) == -1) 
        printf("getsockname() failed");
    
    printf("port=%d \n", addr.sin_port);
    return 0;

【讨论】:

问题不是“我如何编写一个尝试绑定到端口 0 的程序?”而是“任何标准都指定了绑定到端口 0 的行为吗?”。这似乎无法回答问题。【参考方案2】:

这是 AF_INET 地址系列的标准记录行为:

http://man7.org/linux/man-pages/man7/ip.7.html

查看 ip_local_port_range,其中包含以下内容:

    An ephemeral port is allocated to a socket in the following circumstances:

          *  the port number in a socket address is specified as 0 when
             calling bind(2);

【讨论】:

【参考方案3】:

据我所知,它是通用的,但我在标准中找不到任何文字说明它是通用的。另一种可能更便携的替代方法是使用带有空服务名称指针和AI_PASSIVE 标志的getaddrinfo。这保证会给你一个sockaddr,你可以bind。这也是让管理员选择哪个本地ip(v4或v6)的正确方法 要绑定的地址。

【讨论】:

【参考方案4】:

它在 4.2BSD 套接字 API 中肯定是“标准的”,大多数其他实现都是从该 API 派生的,但我不知道任何正式的规范实际上是这样说的。

【讨论】:

以上是关于端口为零的绑定会将您绑定到空闲端口。这是便携的吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Nodejs 随机免费 tcp 端口

如何将服务绑定到任何主机的端口?

绑定到端口 80 的未识别进程

绑定到端口 80 的未识别进程

c#udp源端口目的端口不同

怎么绑定域名我在路由器上做了端口映射,怎么绑定到我