端口为零的绑定会将您绑定到空闲端口。这是便携的吗? [关闭]
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 派生的,但我不知道任何正式的规范实际上是这样说的。
【讨论】:
以上是关于端口为零的绑定会将您绑定到空闲端口。这是便携的吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章