關于TCP服務器最大并發連接數有一種誤解就是“因為端口號上限為65535,所以TCP服務器理論上的可承載的最大并發連接數也是65535”。
先說結論:對于TCP服務端進程來說,他可以同時連接的客戶端數量并不受限于可用端口號。并發連接數受限于linux可打開文件數,這個數是可以配置的,可以非常大,所以實際上受限于系統性能。
從理論上說,端口號的作用是在網絡連接中標識應用層的進程,服務端一般使用眾所周知的端口號進行監聽,客戶端連接時系統自動分配端口號。一個服務端進程服務于n個客戶遠程進程,只需要能通過ip地址+端口號的組合把他們區分開即可,沒有必要占用本機的其他端口號,客戶端連接數增加并不會占用服務器端口號,因此端口號并不能限制并發連接數。當然一臺機器上端口號數量的上限確實是65536個,因為tcp首部中使用16bit去存儲端口號。所以如果說65536影響了連接數,只有一種可能,就是同一臺客戶端機子上開n個進程去連同一個服務端進程,因為客戶端ip是同一個,為了區分出這些連接,只能使用客戶端連接的端口號,那么服務端和一個客戶端主機之間的tcp連接數理論上線確實是65536。但是,服務端可以連接n多客戶端機子呢。
實際上,確實有個限制端口號的配置,就是MaxUserPort,這實際上是一臺主機向外連接使用端口數的限制,這個數也可以配置的,可能默認值才5000,實際上對于正常的服務器主機是夠用的,因為你是等別人連接進來的,不是要去連接很多不同的其他主機的。當然你的服務器上可能跑了一些轉發的服務,這樣你就需要對外連接了,如果被限制在這個配置這兒了確實需要改。但是這個MaxUserPort確實和服務器可以承載的來自客戶端的并發連接數沒有關系。
伴隨這個誤解的還有另外一個誤解,就是accept之后產生的已連接套接字占用了新的端口。這個絕對是錯誤的,linux內核不會這么寫的,因為完全沒必要嘛。客戶端連接上來之后產生的這個socket fd就是用來區分客戶端的,里面會填上客戶端的ip和端口作為發包用,來自客戶端的包也會使用這個fd去讀取。可以試試netstat -ano,然后起一個服務器看下,客戶端連上來這后產生的套接字的服務端端口還是監聽的端口。