在 Wikipedia 中对 TCP 的描述是这样的:
服务器端的会话数量仅受内存限制,并且可以随着新连接的到来而增加,但客户端必须在向服务器发送第一个 SYN 之前分配一个随机端口。
第一部分似乎合乎逻辑:服务器仅使用客户端连接到的端口作为源端口,因此仅受(客户端 IP 数量)*(临时客户端端口数量)的限制 - 一个很大的数字。
但是为什么客户端不能做基本相同的事情呢?如果套接字 A 使用临时端口 12345 连接到服务器 1(例如客户端:12345 -> 服务器 1:80),那么为什么套接字 B 不能通过重复使用相同的源端口(客户端:12345 -> 服务器 2:80)连接到服务器 2?这将允许来自单个主机的超过(端口数)个传出 TCP 连接。
TCP 规范中是否有禁止此类端口重用的规定,或者这种限制仅仅是常见 TCP 实现的实际结果?如果是这样,第一种情况的处理方式是否真的与第二种情况不同,或者单个服务器端口上的传入 TCP 连接数实际上也限制为 65535?
为了澄清起见,我正在寻找理论(根据规格)和实际(实现;特别是 Linux)的限制:
- 从单个客户端到任意服务器/端口的传出连接。
(client:* -> *:*)
- 从单个客户端到同一服务器和端口的连接
(client:* -> server:port)
- 显然不能大于 65535。 - 从任何客户端到单个服务器端口的传入连接
(*:* -> server:port)
- 根据引用的段落和上面陈述的原因,我怀疑这个连接大于 65535。
答案1
tcp 会话由地址的所有四个部分定义,并且只有所有四个部分的组合才需要是唯一的。
所以
client ip : source port -> server ip : destination port
只要这些与下一个会话不同,下一个会话就是有效的,即使它使用相同的源端口和客户端 IP。
这在现实中是否可行取决于操作系统的网络堆栈和所使用的 TCP 库的实现。
显然,对于传入连接,传入计数可能远远大于 65535 - 一个繁忙的网站的并发数很容易就远远超过 65000 个连接。
答案2
客户端受到操作系统网络堆栈的限制。任何操作系统都不太可能允许多个进程在套接字连接中使用相同的源端口。理论上,即使在现有客户端操作系统上使用中间服务(例如 HTTP)也可以允许无限连接,类似于 HTTP.SYS 在 Windows 端口 80 上为多个 HTTP 服务器(在不同进程中!)工作的方式。