平時(shí)工作和學(xué)習(xí)中,大家都知道一臺(tái)計(jì)算機(jī)的端口號(hào)總共有65535個(gè),但一臺(tái)計(jì)算機(jī)真的只能建立65535個(gè)TCP的連接嗎?TCP:(Transmission Control Protocol 傳輸控制協(xié)議) 提供面向連接的、可靠的數(shù)據(jù)傳輸。
一個(gè)完整的TCP連接由四個(gè)部分組成:源IP 源端口 目的IP 目的端口 這就是經(jīng)典的socket四元組。
建立一個(gè)TCP連接,需要將兩端的套接字進(jìn)行綁定:源IP地址:源端口號(hào) <---->目標(biāo)IP地址:目標(biāo)端口號(hào),只要確保綁定的套接字不重復(fù),即可完成一個(gè)tcp的連接,由此可見如果端口號(hào)不夠用了,就不斷變換目標(biāo)IP地址和目標(biāo)端口號(hào),保證四元組不重復(fù),就能創(chuàng)建很多個(gè)TCP的連接,由此可見有人說最多只能創(chuàng)建65535個(gè)tcp連接是不正確的。既然如此,那可以創(chuàng)建tcp的數(shù)量有沒有限制呢?
一、系統(tǒng)設(shè)置對(duì)連接數(shù)的限制
1. Linux系統(tǒng)對(duì)可以使用的端口范圍是由具體限制的,具體查看方法如下:
[root?@muyu? ~]# cat /proc/sys/net/ipv4/ip_local_port_range
32768 60999
當(dāng)前的限制是32768-60999 所以此時(shí)可以使用的端口號(hào)只有60999-32768=28231個(gè)
當(dāng)然這個(gè)數(shù)字是可以修改的,(這是系統(tǒng)管理員優(yōu)化操作系統(tǒng)的一個(gè)重點(diǎn))
修改的方法如下:[root?@muyu? ~]# vim /etc/sysctl.conf加入一行:net.ipv4.ip_local_port_range = 1024 60009保存好后執(zhí)行 sysctl -p /etc/sysctl.conf 使其生效[root?@muyu? ~]# cat /proc/sys/net/ipv4/ip_local_port_range 1024 60999
二、文件描述符對(duì)連接數(shù)的限制
Linux下一切皆文件,計(jì)算機(jī)會(huì)為每一個(gè)TCP的連接分配一個(gè)文件描述符,在和目標(biāo)IP進(jìn)行tcp的通信的時(shí)候只需要對(duì)著文件描述符讀寫就可以了。
但是linux 對(duì)可打開的文件描述符的數(shù)量分別作了三個(gè)方面的限制。"系統(tǒng)級(jí):當(dāng)前系統(tǒng)可打開的最大數(shù)量,通過 cat /proc/sys/fs/file-max 查看[root?@muyu? ~]# cat /proc/sys/fs/file-max95861用戶級(jí):指定用戶可打開的最大數(shù)量,通過 cat /etc/security/limits.conf 查看[root?@muyu? ~]# cat /etc/security/limits.conf...* soft nproc 20* hard nproc 50進(jìn)程級(jí):單個(gè)進(jìn)程可打開的最大數(shù)量,通過 cat /proc/sys/fs/nr_open 查看[root?@muyu? ~]# cat /proc/sys/fs/nr_open1048576
當(dāng)然這個(gè)數(shù)字是可以修改的,(這也是系統(tǒng)管理員優(yōu)化操作系統(tǒng)的一個(gè)重點(diǎn))
修改的方法如下:[root?@muyu? ~]# echo 1000 > /proc/sys/fs/nr_open[root?@muyu? ~]# cat /proc/sys/fs/nr_open1000
三、線程對(duì)連接數(shù)的限制
說到這兒就繞不開一個(gè)大名鼎鼎的C10K問題了,問題產(chǎn)生的原因就是當(dāng)服務(wù)器連接數(shù)達(dá)到 1 萬且每個(gè)連接都需要消耗一個(gè)線程資源時(shí),操作系統(tǒng)就會(huì)不停地忙于線程的上下文切換,最終導(dǎo)致系統(tǒng)崩潰。每建一個(gè)TCP連接就創(chuàng)建一個(gè)線程的方式,是傳統(tǒng)的多線程并發(fā)模型,早期的操作系統(tǒng)只支持這種方式?,F(xiàn)在的操作系統(tǒng)都支持 IO 多路復(fù)用的方式,簡單說就是一個(gè)線程可以管理多個(gè) TCP 連接的資源,這樣就可以用少量的線程來管理大量的 TCP 連接了,所以只要采用IO 多路復(fù)用的方式就可以解決這個(gè)問題。
四、內(nèi)存對(duì)連接數(shù)的限制
每一個(gè)TCP連接本身以及這個(gè)連接所用到的緩沖區(qū),都需要占用一定空間的內(nèi)存,大量的連接非常消耗內(nèi)存空間。
想把這個(gè)問題討論清楚,最好咱們先把客戶端和服務(wù)器兩種角色分開來看。你上面舉的QQ 的例子,是當(dāng)操作系統(tǒng)作為服務(wù)器角色在工作。
這個(gè)時(shí)候,還沒有到你糾結(jié) 65535 問題的時(shí)候呢。服務(wù)器一般都監(jiān)聽在某個(gè)固定的端口上。例如 Nginx,一般監(jiān)聽 80。所有來自客戶端的連接都是和服務(wù)器的 80 端口保持連接的。你沒看錯(cuò),服務(wù)器上只消耗 80 這一個(gè)端口。但卻完全可以支撐下面這些連接
連接1:客戶端IP1 10000 服務(wù)器IP 80連接2:客戶端IP2 10000 服務(wù)器IP 80連接3:......
非但如此,即使是只有一個(gè)客戶端,也可以向這個(gè)服務(wù)器建立多條連接的。只需要不停變換自己的端口號(hào)就行了。連接1:客戶端IP1 10000 服務(wù)器IP 80連接2:客戶端IP1 10001 服務(wù)器IP 80連接3:......
你看,對(duì)于服務(wù)器來說,一個(gè) 80 端口就可以包打天下了。根本不需要糾結(jié)什么 65535 的問題TG:li9047