端口號超過了65535
一.簡介
因為TCP端口號是16位無符號整數, 最大65535, 所以一台服務器最多支持65536個TCP socket連接
這句話是錯誤的,實際上是最多監聽TCP的端口號是65536,就像一台服務器安裝了一個nginx,他的默認端口是80,但可以改為65535。
那他提供了80服務,支持的TCP連接可以是幾十萬個,也就是提供幾十萬個客戶端去訪問。
二.原理
系統通過一個四元組來唯一標識一條TCP連接.,這個四元組的結構是{local ip, local port, remote ip, remote port}, 對於IPv4, 系統理論上最多可以管理2^(32+16+32+16), 2的96次方個連接。
如果不僅僅考慮TCP, 則是一個五元組, 加上協議號(TCP, UDP或者其它)。
如果某個客戶端向同一個TCP端點(ip:port)發起主動連接, 那么每一條連接都必須使用不同的本地TCP端點, 如果客戶端只有一個IP則是使用不同的本地端口, 該端口的范圍在*nix系統上的一個例子是32768到61000, 可以通過如下命令查看:
[root@benegg.com ~]# cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000
也就是說, 一個客戶端連接同一個服務器的同一個ip:port(比如進行壓力測試), 最多可以發起30000個左右的連接.
TCP客戶端(TCP的主動發起者)可以在同一ip:port上向不同的服務器發起主動連接, 只需在bind之前對socket設置SO_REUSEADDR選項.
系統支持的最大打開文件描述符數(包括socket連接):
[root@benegg.com ~]# cat /proc/sys/fs/file-max
580382
單個進程所能打開的最大文件描述符數:
[root@benegg.com ~]# ulimit -n
1024
三.端口號超過65535
下圖顯示的終端端口為 78650 ,那么端口數能否超過 65535 呢?
因為 TCP PORT 大小為 16 bit ,所以不能超過 65535 。
不過 Windows 會有一個問題,telnet www.sina.com.cn 65616 大家可以測試一下,這實際上是訪問 www.sina.com.cn 的 80 端口,為什么呢?
注:65616 - 65536 = 80
以下是引用片段:
main()
{
unsigned short int tcp_port=65616;
printf("%u",tcp_port);
}
有 些軟件,比方說 Windows 的 Telnet ,可能用了 32 bit 的數據類型記錄 port ,這樣 port 表面上看到是可以超過 65535 ,但是 tcp header 明確定義了 tcpport 為 16 bit,那即便某些應用程序使用了 32 bit 的數據類型,最終結果也是被強制轉換。
簡單的來說就是:
- 在應用程序里邊可以使用4字節或更多字節來儲存端口號。
- 當調用了系統的tcp/ip通訊之后,系統底層強制將大於65536的端口轉換回正常范圍。
- 並且在轉換過程中,不會返回任何錯誤信息,一切都悄然進行了,所以應用層的程序不會有任何特別反應,這一切都在系統底層悄然完成了。
- 轉換的方式為:端口號 - 65536 = ?,問號處既是轉換結果。
- 如果轉換后的端口還超過65535呢?那就繼續轉換,直到小於等於65535為止,所以 telnet www.baidu.com 131152 也是可以完美執行的,(65536 + 65536 + 80 = 131152)。