如何在TCP套接字编程中让内核选择1024到5000之间的端口号

21
当我运行以下代码时:
struct   sockaddr_in sin;
int addrlen;   
addrlen=sizeof(sin);   
memset(&sin, 0, sizeof(sin));  
sin.sin_family = AF_INET;  
sin.sin_addr.s_addr=inet_addr("123.456.789.112");  
sin.sin_port=htons(0); // so that the kernel reserves a unique port for us  
sd_server = socket(PF_INET, SOCK_STREAM, 0);  
bind(sd_server, (struct sockaddr *) &sin, sizeof(sin));  
getsockname(sd_server,(struct sockaddr*)&sin,&addrlen);  
port=ntohs(sin.sin_port); 
printf("port number = %d\n",port);

根据套接字,我必须获取1024到5000之间的端口号,但我得到的端口号大约在30,000左右。
我应该怎么办?


C POSIX API,从您的代码中推断?Python:https://dev59.com/questions/5HM_5IYBdhLWcg3wdy_z || Java:https://dev59.com/questions/8nE85IYBdhLWcg3wpFOu || Shell:http://unix.stackexchange.com/questions/55913/whats-the-easiest-way-to-find-an-unused-local-port - Ciro Santilli OurBigBook.com
2个回答

36

端口号的范围是0到65535(尽管通常0具有特殊含义)。在原始的BSD TCP实现中,只有root可以绑定到1到1023的端口,并且动态分配的端口从1024到5000的范围内分配;其余端口可供非特权静态分配使用。如今,1024到5000经常无法满足需要大量动态端口的服务器,因此IANA现已正式指定49152到65535的范围用于动态端口分配。但即使这样也不足以满足某些繁忙服务器的动态端口需求,因此该范围通常由管理员进行配置。在现代Linux和Solaris系统(通常用作服务器),默认的动态范围现在从32768开始。Mac OS X和Windows Vista的默认范围为49152到65535。

linux$ cat /proc/sys/net/ipv4/ip_local_port_range 
32768   61000

solaris$ /usr/sbin/ndd /dev/tcp tcp_smallest_anon_port tcp_largest_anon_port
32768

65535

macosx$ sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.last: 65535

vista> netsh int ipv4 show dynamicport tcp
Protocol tcp Dynamic Port Range
---------------------------------
Start Port : 49152
Number of Ports : 16384 

请随意在这里发布关于IANA范围过小的情况的链接。我很好奇这种情况发生的频率有多高,因为这似乎是一个奇怪的默认设置,似乎只适用于一些繁忙的服务器,而不是大多数情况。 - August Lilleaas
有趣的是,在Win7x64 Ultimate上运行netsh int ipv4 show dynamicport tcp命令返回了以下结果:起始端口:1025端口数量:64510。这个结果出乎意料(至少对我来说是这样)。 - Basic
这些是临时端口吗? - ctrl-alt-delor
@ctrl-alt-delor 是的,动态端口和临时端口是同一概念的两个术语。 - mark4o

6

查看您所使用的平台的sysctl。这是我在我的Mac上看到的内容:


nickf@goblin:~$ sysctl -a|grep port
...
net.inet.ip.portrange.hilast: 65535
net.inet.ip.portrange.hifirst: 49152
net.inet.ip.portrange.last: 65535
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.lowlast: 600
net.inet.ip.portrange.lowfirst: 1023
...

这些是内核查看短暂端口的范围。


2
是的,在Linux上我有:sysctl -a 2>/dev/null | grep ip_local_port_rangenet.ipv4.ip_local_port_range = 32768 61000 - lothar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接