net.ipv4.ip_local_port_range的含义

在《深入分析Java Web技术内幕》一书中看到下面这段话:

要能够建立一个TCP连接,必须知道对方的IP和一个未被使用的端口号,由于32位操作系统的端口号通常由两个字节表示,也就是只有216=65535个,所以一台主机能够同时建立的连接数是有限的,当然操作系统还有一些端口0~1024是受保护的,如80端口、22端口,这些端口都不能被随意占用。

在Linux中可以通过查看/proc/sys/net/ipv4/ip_local_port_range文件来知道当前这个主机可以使用的端口范围。

看完这段话我对几个地方都有点质疑:
1. 32位操作系统的端口号通常由两个字节表示,难道64位机器的端口号还能超过两个字节?大于65535的端口从来没见过。应该是和协议规定的有关系,我在计网复习05-传输层中对TCP和UDP的报文格式都有描述,无论是TCP还是UDP的报文头部都有一个两字节的源端口号和两字节的目的端口号,这应该是TCP/IP协议对端口号长度做出的规定。
2. 所以一台主机能够同时建立的连接数是有限的,原因讲的很模糊,他提到和端口的数量有关系,但实际上我们说一个socket连接是由一个四元组唯一标识的,即两个socket(两台主机的ip和端口号),这四个属性中任何一个不一样都可以是的socket连接,而另一台主机是不确定的,所以应该说两台主机之间能够同时建立的连接数是有限的,这里可能上下文是这个意思,但没有表述清楚。
3. 操作系统还有一些端口0~1024是受保护的,如80端口、22端口,这些端口都不能被随意占用在Linux中可以通过查看/proc/sys/net/ipv4/ip_local_port_range文件来知道当前这个主机可以使用的端口范围。,显然作者对端口号的划分没有很好的理解,后面这句话也有很明显的错误。我在计网复习05-传输层的第一节的思维导图中有总结端口号的分类,但当时没有详谈,看到这段话之后查阅了相关资料,这里详细介绍一下。

端口的分类

计网复习05-传输层这一篇的思维导图中先把端口号分为了服务端使用的端口(0-49151)和客户端使用的端口(49151-65535)。实际上这是不一定的,没有强制要求服务端和客户端只能使用这个端口范围,这应该是tcp/ip协议的建议,并且很明显这个建议也被广泛采纳,这不意味着服务器就不可以使用(49151-65535)中的端口作为长期服务端口。

下面介绍的端口分类对应的范围是由IANA(互联网数字分配机构)规定的。

熟知端口

熟知端口(WellKnown Ports),数值一般为 0 ~ 1023

0端口是保留端口,在编程API中(特别是linux socket编程)作为请求系统分配的(动态)端口。

很多知名的应用层协议会选择这个端口范围内的端口号,例如HTTP服务默认的端口号是80,HTTPS是443,DNS是53、FTP是20、21,SSH是22等。所以一般不推荐没有熟知端口号的应用程序使用这部分的端口号,否则很容易冲突,但不意味着只有这些应用程序才能使用这部分的端口号,只要不冲突,其他服务也能使用这些端口,但是linux中root权限用户的才可以启用1~1023的服务。

登记端口号

登记端口号(Registered Ports),数值为 1024 ~ 49151,为没有熟知端口号的应用程序使用的。

短暂端口号

短暂端口号(Ephemeral Ports),也被称为动态端口(Dynamic Ports),IANA推荐使用 49152 ~ 65535,留给客户进程选择暂时使用。这是什么意思呢?客户端使用TCP、UDP协议与服务端进行连接时,通常会从这个端口范围内被随机分配一个未使用的端口,从而与服务端建立socket连接。这个分配的端口是临时的,仅在通信会话期间有效,所以称为“短暂端口”,与服务器上长期服务的端口区分开。

虽然说推荐是客户端使用的,但实际上服务器也能使用这一部分的端口号做长期服务。

49152 ~ 65535是IANA推荐使用的短暂端口号范围,而linux默认使用的短暂端口号范围实际上是32768到60999,也就是我们使用命令cat /proc/sys/net/ipv4/ip_local_port_rangesysctl -a|grep ip_local_port_range看到的两个数字。linux严格遵守这个配置,作为客户端建立socket连接时只会从这个端口范围获取动态分配的端口。

下面谈谈如何修改这个值,显然修改这个值能明显提高linux作为客户端能建立的并发连接数。因为tcp常常因为time_wait状态占用大量短暂端口,适当提高这个范围也可以减少端口不够用的影响。

linux修改方法:

vi /etc/sysctl.conf

修改

net.ipv4.ip_local_port_range = 1024 65535

然后

sysctl -p

生效

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/net-ipv4-ip_local_port_range%e7%9a%84%e5%90%ab%e4%b9%89/

发表评论

电子邮件地址不会被公开。