TCP socket编程中如何让内核在(1024,5000)范围内选择一个端口号

Posted

技术标签:

【中文标题】TCP socket编程中如何让内核在(1024,5000)范围内选择一个端口号【英文标题】:How to let kernel choose a port number in the range (1024,5000) in TCP socket programming 【发布时间】:2010-10-29 03:34:23 【问题描述】:

当我运行以下代码时:

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,从你的代码中推断?蟒蛇:***.com/questions/1365265/… ||爪哇:***.com/questions/2675362/… ||壳牌:unix.stackexchange.com/questions/55913/… 【参考方案1】:

端口号的范围为 0..65535(尽管 0 通常具有特殊含义)。在最初的 BSD TCP 实现中,只有root 可以绑定到端口 1..1023,并且动态分配的端口是从 1024..5000 范围内分配的;其他可用于非特权静态分配。这些天 1024..5000 通常是不够的动态端口,IANA has now officially designated the range 49152..65535 for dynamic port assignment。然而,对于一些繁忙的服务器来说,即使这样也不够动态端口,所以范围通常是可配置的(由管理员)。在现代 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 范围太小池的情况的链接。我很好奇这种情况发生的频率,似乎是一个奇怪的默认设置,因为它似乎只适用于一些繁忙的服务器,而不是大多数情况。 有趣的是,Win7x64 Ultimate 上的netsh int ipv4 show dynamicport tcp 返回...Start port: 1025Number of Ports : 64510 这出乎意料(至少对我而言) 这些是临时端口吗? @ctrl-alt-delor 是的,动态端口和临时端口是同一事物的两个术语。【参考方案2】:

查看您的平台的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
...

这些是内核窥视临时端口的范围。

【讨论】:

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

以上是关于TCP socket编程中如何让内核在(1024,5000)范围内选择一个端口号的主要内容,如果未能解决你的问题,请参考以下文章

winsocket udp和tcp编程,缓冲区应该设置多大?

Python 之 Socket编程(TCP/UDP)

socket编程

1socket+threading编程之TCP

手把手写C++服务器(24):socket响应一般框架TCP修改缓冲区内核监听listen最大长度

python socket编程tcp/udp俩连接