新聞中心
Socket通信技術(shù)是網(wǎng)絡(luò)編程的核心知識(shí)之一,它是一種為應(yīng)用程序提供網(wǎng)絡(luò)通信功能的編程接口。在Linux操作系統(tǒng)中,Socket通信技術(shù)被廣泛應(yīng)用于網(wǎng)絡(luò)編程、并發(fā)編程等領(lǐng)域。本文介紹Linux中Socket通信技術(shù)的基礎(chǔ)知識(shí)、應(yīng)用場景、實(shí)現(xiàn)方法以及相關(guān)的優(yōu)化技巧,希望能夠幫助開發(fā)者更好地掌握Socket通信技術(shù)。

10年積累的網(wǎng)站建設(shè)、成都網(wǎng)站制作經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站設(shè)計(jì)后付款的網(wǎng)站建設(shè)流程,更有彭山免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
一、Socket通信技術(shù)基礎(chǔ)知識(shí)
1.1、Socket的概念
Socket,又稱“套接字”,是一種用于網(wǎng)絡(luò)編程的編程接口,由操作系統(tǒng)提供。它用于描述一個(gè)網(wǎng)絡(luò)中的進(jìn)程間通信的一種機(jī)制,可以用于在同一主機(jī)或不同主機(jī)之間的進(jìn)程間通信。
1.2、Socket通信的類型
Socket通信根據(jù)數(shù)據(jù)傳輸時(shí)的通信方式,可以分為兩種類型:流式Socket(SOCK_STREAM)和數(shù)據(jù)報(bào)式Socket(SOCK_DGRAM)。
– 流式Socket:基于TCP協(xié)議,面向連接的,例如HTTP、FTP等。
– 數(shù)據(jù)報(bào)式Socket:基于UDP協(xié)議,不需要建立連接,傳輸速度快,但可靠性低,例如DNS、NTP等。
1.3、Socket通信的模型
Socket通信一般采用C/S(Client/Server)模型,即客戶端和服務(wù)器端之間進(jìn)行通信??蛻舳送ㄟ^套接字(socket)向服務(wù)器發(fā)送請(qǐng)求,服務(wù)器則響應(yīng)請(qǐng)求,并將相應(yīng)的數(shù)據(jù)通過套接字傳輸給客戶端。
1.4、Socket通信的基本流程
Socket通信的基本流程分為4個(gè)步驟:創(chuàng)建Socket -> 綁定Socket -> 監(jiān)聽Socket -> 通信。
– 創(chuàng)建Socket:通過系統(tǒng)調(diào)用socket()函數(shù)創(chuàng)建一個(gè)Socket。
– 綁定Socket:將一個(gè)IP地址和端口號(hào)綁定到Socket上,指定Socket用于接收客戶端請(qǐng)求。
– 監(jiān)聽Socket:調(diào)用listen()函數(shù),將Socket設(shè)置為監(jiān)聽狀態(tài),等待客戶端請(qǐng)求。
– 通信:通過accept()函數(shù)接收客戶端請(qǐng)求,然后將請(qǐng)求發(fā)送給服務(wù)器端進(jìn)行處理,并將處理結(jié)果返回給客戶端,完成一次通信。
二、Socket通信的應(yīng)用場景
Socket通信技術(shù)在網(wǎng)絡(luò)編程中具有廣泛的應(yīng)用,下面介紹幾個(gè)常見的應(yīng)用場景。
2.1、網(wǎng)絡(luò)編程
Socket通信技術(shù)是網(wǎng)絡(luò)編程的核心技術(shù)之一。通過Socket通信,應(yīng)用程序可以在本地或遠(yuǎn)程主機(jī)之間進(jìn)行數(shù)據(jù)傳輸,實(shí)現(xiàn)網(wǎng)絡(luò)通信的功能。
2.2、并發(fā)編程
在并發(fā)編程中,Socket通信技術(shù)可以應(yīng)用于多線程、多進(jìn)程之間進(jìn)行通信。應(yīng)用程序可以通過Socket通信,在多個(gè)線程或多個(gè)進(jìn)程之間傳遞數(shù)據(jù),實(shí)現(xiàn)線程或進(jìn)程之間的通信。
2.3、分布式計(jì)算
在分布式計(jì)算中,Socket通信技術(shù)可以用于不同的節(jié)點(diǎn)之間進(jìn)行網(wǎng)絡(luò)通信。通過Socket通信,分布式計(jì)算系統(tǒng)可以將不同節(jié)點(diǎn)的任務(wù)分發(fā)到不同的節(jié)點(diǎn)上進(jìn)行處理,最終將結(jié)果匯總并返回給客戶端。
三、Socket通信的實(shí)現(xiàn)方法
Socket通信的實(shí)現(xiàn)方法可以采用C語言、C++、Java等多種語言進(jìn)行實(shí)現(xiàn)。下面以C語言為例,介紹Socket通信的實(shí)現(xiàn)方法。
3.1、創(chuàng)建Socket
創(chuàng)建Socket可以通過Linux系統(tǒng)調(diào)用socket()函數(shù)實(shí)現(xiàn),需要指定Socket的協(xié)議類型、傳輸方式和協(xié)議參數(shù)。
– 創(chuàng)建流式Socket:
“`c
int sfd = socket(AF_INET, SOCK_STREAM, 0); // 創(chuàng)建流式Socket
“`
– 創(chuàng)建數(shù)據(jù)報(bào)式Socket:
“`c
int sfd = socket(AF_INET, SOCK_DGRAM, 0); // 創(chuàng)建數(shù)據(jù)報(bào)式Socket
“`
3.2、綁定Socket
綁定Socket需要指定一個(gè)IP地址和端口號(hào),可以采用如下代碼實(shí)現(xiàn):
“`c
struct sockaddr_in addr; // 創(chuàng)建Socket地址
addr.sin_family = AF_INET; // 指定地址家族
addr.sin_port = htons(8080); // 指定端口號(hào)
addr.sin_addr.s_addr = htonl(INADDR_ANY); // 指定IP地址
bind(sfd, (struct sockaddr *)&addr, sizeof(addr)); // 綁定Socket地址
“`
3.3、監(jiān)聽Socket
在綁定Socket之后,需要將其設(shè)置成監(jiān)聽狀態(tài),等待客戶端的連接??梢酝ㄟ^listen()函數(shù)實(shí)現(xiàn):
“`c
listen(sfd, 10); // 設(shè)置Socket為監(jiān)聽狀態(tài),最多允許10個(gè)客戶端連接
“`
3.4、通信
通信時(shí),需要接收客戶端的請(qǐng)求并發(fā)送響應(yīng)??梢允褂胊ccept()函數(shù)接收客戶端的請(qǐng)求,并將數(shù)據(jù)發(fā)送給服務(wù)端進(jìn)行處理。
“`c
int cfd = accept(sfd, (struct sockaddr *)&caddr, &len); // 接收客戶端請(qǐng)求,返回客戶端Socket
char buf[1024] = {0};
recv(cfd, buf, sizeof(buf), 0); // 接收客戶端發(fā)送的數(shù)據(jù)
…… // 服務(wù)端進(jìn)行數(shù)據(jù)處理
send(cfd, buf, sizeof(buf), 0); // 將處理結(jié)果返回給客戶端
close(cfd); // 關(guān)閉客戶端Socket
“`
四、Socket通信的優(yōu)化技巧
Socket通信在實(shí)現(xiàn)過程中,需要考慮性能、并發(fā)、可靠性等因素,下面介紹幾個(gè)常用的Socket通信優(yōu)化技巧。
4.1、多線程/多進(jìn)程
通過多線程或多進(jìn)程的方式,可以提高Socket通信的并發(fā)度,同時(shí)提高服務(wù)器的性能。不過,需要注意線程和進(jìn)程之間的同步和數(shù)據(jù)共享的問題,避免出現(xiàn)數(shù)據(jù)沖突和安全問題。
4.2、非阻塞模式
通過設(shè)置Socket為非阻塞模式,可以避免服務(wù)器因?yàn)槟骋粋€(gè)客戶端阻塞而無法響應(yīng)其他客戶端請(qǐng)求的情況。使用非阻塞模式時(shí),服務(wù)器需要定時(shí)檢查所有客戶端的狀態(tài),避免因?yàn)槟骋粋€(gè)客戶端的問題,導(dǎo)致整個(gè)服務(wù)器崩潰。
4.3、TCP_NODELAY選項(xiàng)
通過設(shè)置TCP_NODELAY選項(xiàng),可以優(yōu)化TCP協(xié)議的數(shù)據(jù)傳輸性能。TCP_NODELAY選項(xiàng)可以禁用Naggle算法,立即發(fā)送數(shù)據(jù),提高TCP協(xié)議的響應(yīng)速度和傳輸效率。
4.4、SO_REUSEADDR選項(xiàng)
在服務(wù)器重啟時(shí),如果之前綁定的Socket端口號(hào)還沒有作系統(tǒng)收回,那么可能會(huì)造成服務(wù)器無法啟動(dòng)的情況。通過設(shè)置SO_REUSEADDR選項(xiàng),可以避免這種問題的出現(xiàn)。
Socket通信技術(shù)是網(wǎng)絡(luò)編程的核心知識(shí)之一,它可以用于實(shí)現(xiàn)網(wǎng)絡(luò)通信、并發(fā)編程、分布式計(jì)算等多種應(yīng)用場景。在實(shí)現(xiàn)Socket通信時(shí),需要了解Socket的基礎(chǔ)知識(shí)、應(yīng)用場景、實(shí)現(xiàn)方法以及相關(guān)的優(yōu)化技巧,才能更好地開發(fā)高性能、高可靠性的應(yīng)用程序。
相關(guān)問題拓展閱讀:
- 請(qǐng)問linux怎么增大socket連接上限?
請(qǐng)問linux怎么增大socket連接上限?
增大Linux的socket更大連接數(shù) 最近接的項(xiàng)目是模擬多個(gè)socket 客戶端與服務(wù)器進(jìn)行通信。由于Linux 系統(tǒng)的限制,在linux/include/linux/posix_types.h文件中有如下的宏定義:#undef __FD_SETSIZE#define __FD_SETSIZE 1024這個(gè)宏啟灶是對(duì)更大文件描述符的定義為1024。當(dāng)需要1024個(gè)以上的fd時(shí),例如select()函數(shù)就會(huì)偵聽出錯(cuò)。因此需要將1024改成需要的數(shù)目,但最多不能超過65535。但僅僅修改這個(gè)是不夠的。第二步就需要修改一個(gè)進(jìn)程更大打開的文件數(shù)。其具體步驟是:1、cd /usr/src/linux-2.4/include/linux2、vi limits.h 編輯文件:#define NR_OPEN原值為1024#define OPEN_MAX原值為10243、vi fs.h#define INR_OPEN原值為1024#define NR_FILE原值為8192,這個(gè)值為內(nèi)存64/1M的比率計(jì)算,1G內(nèi)存計(jì)算為:64*1024#define NR_RESERVED_FILES 128 原值為10.4、cd /usr/肢茄src/linux-2.4/include/net5、vi tcp.h#define TCP_LHTABLE_SIZE 128 原值為32.便于listen偵聽隊(duì)列,設(shè)大。設(shè)置更大打開文件數(shù)與內(nèi)存相關(guān),太大系統(tǒng)會(huì)變慢。第三步就是編譯內(nèi)核,其具體步驟是: 1. make clean2. make3. make dep4. make bzImage將bzImage 導(dǎo)入/boot 重啟系統(tǒng)即可!用1024個(gè)歷旁察以上客戶端與服務(wù)器進(jìn)行連接,在服務(wù)器的終端用netstat |wc 命令可以統(tǒng)計(jì)出當(dāng)前建立的socket的連接數(shù)。
1、修改用戶進(jìn)程可打開文件數(shù)限制
在Linux平臺(tái)上,無論編寫客戶端程序還是服務(wù)端程序,在進(jìn)行高并發(fā)TCP連慎游接處理時(shí),
更高的并發(fā)數(shù)量都要受到系統(tǒng)對(duì)用戶單一進(jìn)程同時(shí)可打開文件數(shù)量的限制(這是因?yàn)橄到y(tǒng)
為每個(gè)TCP連接都要?jiǎng)?chuàng)建一個(gè)socket句柄,每個(gè)socket句柄同時(shí)也是一個(gè)文件句柄)。
可使用ulimit命令查看系統(tǒng)允許當(dāng)前用戶進(jìn)程打開的文件數(shù)限制:
$ ulimit -n
1024
這表示當(dāng)前用戶的每個(gè)進(jìn)程最多允許同時(shí)打開1024個(gè)文件,這1024個(gè)文件中還得除去
每個(gè)進(jìn)程必然打開的標(biāo)準(zhǔn)輸入,標(biāo)準(zhǔn)輸出,標(biāo)準(zhǔn)錯(cuò)誤,服務(wù)器監(jiān)聽 socket,
進(jìn)程間通訊的unix域socket等文件,那么剩下的可用于客戶端socket連接的文件數(shù)就
只有大概=1014個(gè)左右。也就是說缺省情況下,基于Linux的通訊程序最多允許
同時(shí)1014個(gè)TCP并發(fā)連接。
對(duì)于想支持更高數(shù)量的TCP并發(fā)連接的通訊處理程序,就必須修改Linux對(duì)當(dāng)前用戶的
進(jìn)程同時(shí)打開的文件數(shù)量的軟限制(soft limit)和硬限制(hardlimit)。其中軟限制
是指Linux在當(dāng)前系統(tǒng)能夠承受的范圍內(nèi)進(jìn)一步限制用戶同時(shí)打開的文件數(shù);硬限制
則是根據(jù)系統(tǒng)硬件資源狀況(主要是系統(tǒng)內(nèi)存)計(jì)算出來的系統(tǒng)最多可同時(shí)打開的文件數(shù)量。
通常軟限制小于或等于硬限制。
修改上述限制的最簡單的辦法就是使用ulimit命令:
$ ulimit -n
上述命令中,在中指定要設(shè)置的單一進(jìn)程允許打開的更大文件數(shù)。如果系統(tǒng)回顯
類似于“Operation notpermitted”之類的話,說明上述限制修改失敗,實(shí)際上是
因?yàn)樵谥兄付ǖ臄?shù)值超過了Linux系統(tǒng)對(duì)該用戶打開文件數(shù)的軟限制或硬限制。
因此,就需要修改Linux系統(tǒng)對(duì)用戶的關(guān)于打開文件數(shù)的軟限制和硬限制。
之一步,修改/etc/security/limits.conf文件,在文件中添加如下行:
speng soft nofile 10240
speng hard nofile 10240
其中speng指定了要修改哪個(gè)用戶的打開文件數(shù)限制,可用’*’號(hào)表示修改所有用戶的限制;
soft或hard指定要修改軟限制還是硬限制;10240則指定了想要修改的新的限制值,
即更大打開文件數(shù)(請(qǐng)注意軟限制值要小于或等于硬限制)。修改完后保存文件。
第二步,修改/etc/pam.d/login文件,在文件中添加如下行:
session required /lib/security/pam_limits.so
這是告訴Linux在用戶完成系統(tǒng)登錄后,應(yīng)該調(diào)用pam_limits.so模塊來設(shè)置系統(tǒng)對(duì)
該用戶可使用的各種資源數(shù)量的更大限制(包括用戶可打開的更大文件數(shù)限制),
而pam_limits.so模塊就會(huì)從/etc/security/limits.conf文件中讀取配置來設(shè)置這些限制值。
修改完后保存此文件。
第三步,查看Linux系統(tǒng)級(jí)的更大打開文件數(shù)限制,使用如下命令:
$ cat /proc/sys/fs/file-max
12158
這表明這臺(tái)Linux系統(tǒng)最多允許同時(shí)打開(即包含所有用戶打開文件數(shù)總和)12158個(gè)文件,
是Linux系統(tǒng)級(jí)硬限制,所有用戶級(jí)的打開文件數(shù)限制都不應(yīng)超過這個(gè)數(shù)值。通常這個(gè)系統(tǒng)級(jí)
硬限制是Linux系統(tǒng)在啟動(dòng)時(shí)根據(jù)系統(tǒng)硬件資源狀況計(jì)算出來的更佳的更大同時(shí)打開文件數(shù)限制,
如果沒有特殊需要,不應(yīng)該修改此限制,除非想為用戶級(jí)打開文件數(shù)限制設(shè)置超過此限制的值。
修改此硬限制的方法是修改/etc/rc.local腳本,在腳本中添加如下行:
echo> /proc/sys/fs/file-max
這是讓Linux在啟動(dòng)完成后強(qiáng)行將系統(tǒng)級(jí)打開文件數(shù)硬限制設(shè)置為22158。修改完后保存此文件。
完成上述步驟后重啟系統(tǒng),一般情況下就可以明孝巧將Linux系統(tǒng)對(duì)指定用戶的單一進(jìn)程允許同時(shí)
打開的更大文件數(shù)限制設(shè)為指定的數(shù)值。如果重啟后用 ulimit-n命令查看用戶可打開文件數(shù)限制
仍然低于上述步驟中設(shè)置的更大值,這可激鍵能是因?yàn)樵谟脩舻卿浤_本/etc/profile中使用ulimit -n命令
已經(jīng)將用戶可同時(shí)打開的文件數(shù)做了限制。由于通過ulimit-n修改系統(tǒng)對(duì)用戶可同時(shí)打開文件的
更大數(shù)限制時(shí),新修改的值只能小于或等于上次 ulimit-n設(shè)置的值,因此想用此命令增大這個(gè)
限制值是不可能的。
所以,如果有上述問題存在,就只能去打開/etc/profile腳本文件,
在文件中查找是否使用了ulimit-n限制了用戶可同時(shí)打開的更大文件數(shù)量,如果找到,
則刪除這行命令,或者將其設(shè)置的值改為合適的值,然后保存文件,用戶退出并重新登錄系統(tǒng)即可。
通過上述步驟,就為支持高并發(fā)TCP連接處理的通訊處理程序解除關(guān)于打開文件數(shù)量方面的系統(tǒng)限制。
2、修改網(wǎng)絡(luò)內(nèi)核對(duì)TCP連接的有關(guān)限制
在Linux上編寫支持高并發(fā)TCP連接的客戶端通訊處理程序時(shí),有時(shí)會(huì)發(fā)現(xiàn)盡管已經(jīng)解除了系統(tǒng)
對(duì)用戶同時(shí)打開文件數(shù)的限制,但仍會(huì)出現(xiàn)并發(fā)TCP連接數(shù)增加到一定數(shù)量時(shí),再也無法成功
建立新的TCP連接的現(xiàn)象。出現(xiàn)這種現(xiàn)在的原因有多種。
之一種原因可能是因?yàn)長inux網(wǎng)絡(luò)內(nèi)核對(duì)本地
端口號(hào)
范圍有限制。此時(shí),進(jìn)一步分析為什么無法
建立TCP連接,會(huì)發(fā)現(xiàn)問題出在connect()調(diào)用返回失敗,查看系統(tǒng)錯(cuò)誤提示消息是“Can’t assign requestedaddress”。同時(shí),如果在此時(shí)用tcpdump工具監(jiān)視網(wǎng)絡(luò),會(huì)發(fā)現(xiàn)根本沒有TCP連接時(shí)客戶端
發(fā)SYN包的網(wǎng)絡(luò)流量。這些情況說明問題在于本地Linux系統(tǒng)內(nèi)核中有限制。
其實(shí),問題的根本原因
在于
Linux內(nèi)核
的TCP/IP協(xié)議實(shí)現(xiàn)模塊對(duì)系統(tǒng)中所有的客戶端TCP連接對(duì)應(yīng)的本地端口號(hào)的范圍
進(jìn)行了限制(例如,內(nèi)核限制本地端口號(hào)的范圍為1024~32768之間)。當(dāng)系統(tǒng)中某一時(shí)刻同時(shí)
存在太多的TCP客戶端連接時(shí),由于每個(gè)TCP客戶端連接都要占用一個(gè)唯一的本地端口號(hào)
(此端口號(hào)在系統(tǒng)的本地端口號(hào)范圍限制中),如果現(xiàn)有的TCP客戶端連接已將所有的本地端口號(hào)占滿,
則此時(shí)就無法為新的TCP客戶端連接分配一個(gè)本地端口號(hào)了,因此系統(tǒng)會(huì)在這種情況下在connect()
調(diào)用中返回失敗,并將錯(cuò)誤提示消息設(shè)為“Can’t assignrequested address”。
有關(guān)這些控制
邏輯可以查看Linux內(nèi)核源代碼,以linux2.6內(nèi)核為例,可以查看tcp_ipv4.c文件中如下函數(shù):
static int tcp_v4_hash_connect(struct sock *sk)
請(qǐng)注意上述函數(shù)中對(duì)變量sysctl_local_port_range的訪問控制。變量sysctl_local_port_range
的初始化則是在tcp.c文件中的如下函數(shù)中設(shè)置:
void __init tcp_init(void)
內(nèi)核編譯時(shí)默認(rèn)設(shè)置的本地端口號(hào)范圍可能太小,因此需要修改此本地端口范圍限制。
之一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_local_port_range =
這表明將系統(tǒng)對(duì)本地端口范圍限制設(shè)置為1024~65000之間。請(qǐng)注意,本地端口范圍的最小值
必須大于或等于1024;而端口范圍的更大值則應(yīng)小于或等于65535。修改完后保存此文件。
第二步,執(zhí)行sysctl命令:
$ sysctl -p
如果系統(tǒng)沒有錯(cuò)誤提示,就表明新的本地端口范圍設(shè)置成功。如果按上述端口范圍進(jìn)行設(shè)置,
則理論上單獨(dú)一個(gè)進(jìn)程最多可以同時(shí)建立60000多個(gè)TCP客戶端連接。
第二種無法建立TCP連接的原因可能是因?yàn)長inux網(wǎng)絡(luò)內(nèi)核的IP_TABLE防火墻對(duì)更大跟蹤的TCP
連接數(shù)有限制。此時(shí)程序會(huì)表現(xiàn)為在 connect()調(diào)用中阻塞,如同死機(jī),如果用tcpdump工具監(jiān)視網(wǎng)絡(luò),
也會(huì)發(fā)現(xiàn)根本沒有TCP連接時(shí)客戶端發(fā)SYN包的網(wǎng)絡(luò)流量。由于 IP_TABLE防火墻在內(nèi)核中會(huì)對(duì)
每個(gè)TCP連接的狀態(tài)進(jìn)行跟蹤,跟蹤信息將會(huì)放在位于內(nèi)核內(nèi)存中的conntrackdatabase中,
這個(gè)數(shù)據(jù)庫的大小有限,當(dāng)系統(tǒng)中存在過多的TCP連接時(shí),數(shù)據(jù)庫容量不足,IP_TABLE無法為
新的TCP連接建立跟蹤信息,于是表現(xiàn)為在connect()調(diào)用中阻塞。此時(shí)就必須修改內(nèi)核對(duì)更大跟蹤
的TCP連接數(shù)的限制,方法同修改內(nèi)核對(duì)本地端口號(hào)范圍的限制是類似的:
之一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_conntrack_max = 10240
這表明將系統(tǒng)對(duì)更大跟蹤的TCP連接數(shù)限制設(shè)置為10240。請(qǐng)注意,此限制值要盡量小,
以節(jié)省對(duì)內(nèi)核內(nèi)存的占用。
第二步,執(zhí)行sysctl命令:
$ sysctl -p
如果系統(tǒng)沒有錯(cuò)誤提示,就表明系統(tǒng)對(duì)新的更大跟蹤的TCP連接數(shù)限制修改成功。
如果按上述參數(shù)進(jìn)行設(shè)置,則理論上單獨(dú)一個(gè)進(jìn)程最多可以同時(shí)建立10000多個(gè)TCP客戶端連接。
3、使用支持高并發(fā)網(wǎng)絡(luò)I/O的編程技術(shù)
在Linux上編寫高并發(fā)TCP連接
應(yīng)用程序
時(shí),必須使用合適的網(wǎng)絡(luò)I/O技術(shù)和I/O事件分派機(jī)制。
可用的I/O技術(shù)有同步I/O,非阻塞式同步I/O(也稱反應(yīng)式I/O),以及異步I/O。在高TCP并發(fā)的情形下,
如果使用同步I/O,這會(huì)嚴(yán)重阻塞程序的運(yùn)轉(zhuǎn),除非為每個(gè)TCP連接的I/O創(chuàng)建一個(gè)線程。
但是,過多的線程又會(huì)因系統(tǒng)對(duì)線程的調(diào)度造成巨大開銷。因此,在高TCP并發(fā)的情形下使用
同步 I/O是不可取的,這時(shí)可以考慮使用非阻塞式同步I/O或異步I/O。非阻塞式同步I/O的技術(shù)包括使用select(),poll(),epoll等機(jī)制。異步I/O的技術(shù)就是使用AIO。
從I/O事件分派機(jī)制來看,使用select()是不合適的,因?yàn)樗С值牟l(fā)連接數(shù)有限(通常在1024個(gè)以內(nèi))。
如果考慮性能,poll()也是不合適的,盡管它可以支持的較高的TCP并發(fā)數(shù),但是由于其采用
“輪詢”機(jī)制,當(dāng)并發(fā)數(shù)較高時(shí),其運(yùn)行效率相當(dāng)?shù)?,并可能存在I/O事件分派不均,導(dǎo)致部分TCP
連接上的I/O出現(xiàn)“饑餓”現(xiàn)象。而如果使用epoll或AIO,則沒有上述問題(早期Linux內(nèi)核的AIO技術(shù)
實(shí)現(xiàn)是通過在內(nèi)核中為每個(gè) I/O請(qǐng)求創(chuàng)建一個(gè)線程來實(shí)現(xiàn)的,這種實(shí)現(xiàn)機(jī)制在高并發(fā)TCP連接的情形下
使用其實(shí)也有嚴(yán)重的性能問題。但在最新的Linux內(nèi)核中,AIO的實(shí)現(xiàn)已經(jīng)得到改進(jìn))。
綜上所述,在開發(fā)支持高并發(fā)TCP連接的Linux應(yīng)用程序時(shí),應(yīng)盡量使用epoll或AIO技術(shù)來實(shí)現(xiàn)并發(fā)的
TCP連接上的I/O控制,這將為提升程序?qū)Ω卟l(fā)TCP連接的支持提供有效的I/O保證。
內(nèi)核參數(shù)sysctl.conf的優(yōu)化
/etc/sysctl.conf 是用來控制linux網(wǎng)絡(luò)的配置文件,對(duì)于依賴網(wǎng)絡(luò)的程序(如web服務(wù)器和cache服務(wù)器)
非常重要,RHEL默認(rèn)提供的更好調(diào)整。
推薦配置(把原/etc/sysctl.conf內(nèi)容清掉,把下面內(nèi)容復(fù)制進(jìn)去):
net.ipv4.ip_local_port_range =
net.core.rmem_max=
net.core.wmem_max=
net.ipv4.tcp_rmem=77216
net.ipv4.tcp_wmem=77216
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_window_scaling = 0
net.ipv4.tcp_sack = 0
net.core.netdev_max_backlog = 30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn =
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_max_orphans =
net.ipv4.tcp_max_syn_backlog =
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
這個(gè)配置參考于cache服務(wù)器varnish的推薦配置和SunOne 服務(wù)器系統(tǒng)優(yōu)化的推薦配置。
varnish調(diào)優(yōu)推薦配置的地址為:
不過varnish推薦的配置是有問題的,實(shí)際運(yùn)行表明“net.ipv4.tcp_fin_timeout = 3”的配置
會(huì)導(dǎo)致頁面經(jīng)常打不開;并且當(dāng)網(wǎng)友使用的是IE6瀏覽器時(shí),訪問網(wǎng)站一段時(shí)間后,所有網(wǎng)頁都會(huì)
打不開,重啟瀏覽器后正常??赡苁菄獾木W(wǎng)速快吧,我們國情決定需要
調(diào)整“net.ipv4.tcp_fin_timeout = 10”,在10s的情況下,一切正常(實(shí)際運(yùn)行結(jié)論)。
修改完畢后,執(zhí)行:
/in/sysctl -p /etc/sysctl.conf
/in/sysctl -w net.ipv4.route.flush=1
命令生效。為了保險(xiǎn)起見,也可以reboot系統(tǒng)。
調(diào)整文件數(shù):
linux系統(tǒng)優(yōu)化完網(wǎng)絡(luò)必須調(diào)高系統(tǒng)允許打開的文件數(shù)才能支持大的并發(fā),默認(rèn)1024是遠(yuǎn)遠(yuǎn)不夠的。
執(zhí)行命令:
Shell代碼
echo ulimit -HSn>> /etc/rc.local
echo ulimit -HSn>>/root/.bash_profile
socket() linux的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于socket linux,Linux中的Socket通信技術(shù),請(qǐng)問linux怎么增大socket連接上限?的信息別忘了在本站進(jìn)行查找喔。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
本文名稱:Linux中的Socket通信技術(shù)(socketlinux)
網(wǎng)頁地址:http://m.5511xx.com/article/dpdhpih.html


咨詢
建站咨詢
