Linux下高性能網絡編程中的幾個TCP/IP選項_SO_REUSEADDR、SO_RECVBUF、SO_SNDBUF、SO_KEEPALIVE、SO_LINGER、TCP_CORK、TCP_NODE

? ? ? ? 最近在新的平臺上測試程序,以前一些沒有注意到的問題都成為了性能瓶頸,通過設置一些TCP/IP選項能夠解決一部分問題,當然根本的解決方法是重構代碼,重新設計服務器框架。先列出幾個TCP/IP選項:

選項
man 7 socket:
SO_REUSEADDR
SO_RECVBUF/SO_SNDBUF
SO_KEEPALIVE
SO_LINGER
man 7 tcp:
TCP_CORK
TCP_NODELAY
TCP_DEFER_ACCEPT
TCP_KEEPCNT/TCP_KEEPIDLE/TCP_KEEPINTVL
SO_REUSEADDR

man 命令的?領域?名稱 說明
1 用戶命令, 可由任何人啟動的。
2 系統調用, 即由內核提供的函數。
3 例程, 即庫函數。
4 設備, 即/dev目錄下的特殊文件。
5 文件格式描述, 例如/etc/passwd。
6 游戲, 不用解釋啦!
7 雜項, 例如宏命令包、慣例等。
8 系統管理員工具, 只能由root啟動。
9 其他(Linux特定的), 用來存放內核例行程序的文檔。

SO_REUSEADDR選項:

在服務器程序中,SO_REUSEADDR socket選項通常在調用bind()之前被設置。
SO_REUSEADDR可以用在以下四種情況下:?
(摘自《Unix網絡編程》卷一,即UNPv1)
1、當有一個有相同本地地址和端口的socket1處于TIME_WAIT狀態時,而你啟動的程序的socket2要占用該地址和端口,你的程序就要用到該選項。?
2、SO_REUSEADDR允許同一port上啟動同一服務器的多個實例(多個進程)。但每個實例綁定的IP地址是不能相同的在有多塊網卡或用IP Alias技術的機器可以測試這種情況。?
3、SO_REUSEADDR允許單個進程綁定相同的端口到多個socket上,但每個socket綁定的ip地址不同。這和2很相似,區別請看UNPv1。?
4、SO_REUSEADDR允許完全相同的地址和端口的重復綁定。但這只用于UDP的多播,不用于TCP

TCP_NODELAY/TCP_CHORK選項:
TCP_NODELAY/TCP_CHORK
TCP_NODELAY和TCP_CORK基本上控制了包的“Nagle化”,Nagle化在這里的含義是采用Nagle算法把較小的包組裝為更大的幀。TCP_NODELAY和TCP_CORK都禁掉了Nagle算法,只不過他們的行為不同而已。
TCP_NODELAY 不使用Nagle算法,不會將小包進行拼接成大包再進行發送,直接將小包發送出去,會使得小包時候用戶體驗非常好。

Nagle算法參見自己的博客:http://blog.163.com/xychenbaihu@yeah/blog/static/132229655201231214038740/
當在傳送大量數據的時候,為了提高TCP發送效率,可以設置TCP_CORK,CORK顧名思義,就是"塞子"的意思,它會盡量在每次發送最大的數據量。當設置了TCP_CORK后,會有阻塞200ms,當阻塞時間過后,數據就會自動傳送。
詳細的資料可以查看參考文獻5。

SO_LINGER選項:
SO_LINGER
linger,顧名思義是延遲延緩的意思,這里是延緩面向連接的socket的close操作。

默認,close立即返回,但是當發送緩沖區中還有一部分數據的時候,系統將會嘗試將數據發送給對端。SO_LINGER可以改變close的行為。

控制SO_LINGER通過下面一個結構:
struct linger
{
????? int l_onoff; /*0=off, nonzero=on*/
????? int l_linger; /*linger time, POSIX specifies units as seconds*/
};
通過結構體中成員的不同賦值,可以表現為下面幾種情況:
1. l_onoff設置為0,選項被關閉。l_linger值被忽略,就是上面的默認情形,close立即返回。
2. l_onoff設置為非0,l_linger被設置為0,則close()不被阻塞立即執行,丟棄socket發送緩沖區中的數據,并向對端發送一個RST報文。

????這種關閉方式稱為“強制”或“失效”關閉。
3. l_onoff設置為非0,l_linger被設置為非0,則close()調用阻塞進程,直到所剩數據發送完畢或超時。

????這種關閉稱為“優雅的”關閉。
注意:
?????? 這個選項需要謹慎使用,尤其是強制式關閉,會丟失服務器發給客戶端的最后一部分數據。UNP中:
The TIME_WAIT state is our friend and is there to help us(i.e., to let the old duplicate segments expire in the network).

?

TCP_DEFER_ACCEPT選項:
TCP_DEFER_ACCEPT
defer accept,從字面上理解是推遲accept,實際上是當接收到第一個數據之后,才會創建連接,三次握手完成,連接還沒有建立

對于像HTTP等非交互式的服務器,這個很有意義,可以用來防御空連接攻擊(只是建立連接,但是不發送任何數據)。
使用方法如下:

val = 5;
setsockopt(srv_socket->fd, SOL_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val)) ;

里面 val 的單位是秒,注意如果打開這個功能,kernel 在 val 秒之內還沒有收到數據,不會繼續喚醒進程,而是直接丟棄連接。如果服務器設置TCP_DEFER_ACCEPT選項后,服務器受到一個CONNECT請求后,三次握手之后,新的socket狀態依然為SYN_RECV,而不是ESTABLISHED,操作系統不會Accept
由于設置TCP_DEFER_ACCEPT選項之后,三次握手后狀態沒有達到ESTABLISHED,而是SYN_RECV。這個時候,如果客戶端一直沒有發送"數據"報文,服務器將重傳SYN/ACK報文,重傳次數受net.ipv4.tcp_synack_retries參數控制,達到重傳次數之后,才會再次進行setsockopt中設置的超時值,因此會出現SYN_RECV生存時間比設置值大一些的情況。
關于SYN_RECV狀態可以查看參考文獻7。

?

SO_KEEPALIVE選項:
SO_KEEPALIVE/TCP_KEEPCNT/TCP_KEEPIDLE/TCP_KEEPINTVL
??????? 如果一方已經關閉或異常終止連接,而另一方卻不知道,我們將這樣的TCP連接稱為半打開的。

??????? TCP通過保活定時器(KeepAlive)來檢測半打開連接。
???????? 在高并發的網絡服務器中,經常會出現漏掉socket的情況,對應的結果有一種情況就是出現大量的CLOSE_WAIT狀態的連接。這個時候,可以通過設置KEEPALIVE選項來解決這個問題,當然還有其他的方法可以解決這個問題,詳細的情況可以查看參考資料8。
使用方法如下:

//Setting For KeepAlive
int keepalive = 1;
setsockopt(incomingsock,SOL_SOCKET,SO_KEEPALIVE,(void*)(&keepalive),(socklen_t)sizeof(keepalive));
int keepalive_time = 30;
setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPIDLE,(void*)(&keepalive_time),(socklen_t)sizeof(keepalive_time));
int keepalive_intvl = 3;
setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPINTVL,(void*)(&keepalive_intvl),(socklen_t)sizeof(keepalive_intvl));
int keepalive_probes= 3;
setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPCNT,(void*)(&keepalive_probes),(socklen_t)sizeof(keepalive_probes));


?????? 設置SO_KEEPALIVE選項來開啟KEEPALIVE,然后通過TCP_KEEPIDLE、TCP_KEEPINTVL和TCP_KEEPCNT設置keepalive的開始時間、間隔、次數等參數。
??????? 當然,也可以通過設置/proc/sys/net/ipv4/tcp_keepalive_time、tcp_keepalive_intvl和tcp_keepalive_probes等內核參數來達到目的,但是這樣的話,會影響所有的socket,因此建議使用setsockopt設置

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/253353.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/253353.shtml
英文地址,請注明出處:http://en.pswp.cn/news/253353.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

云計算在未來一定是不可或缺的

2019獨角獸企業重金招聘Python工程師標準>>> 在2018京東云合作伙伴大會上,京東云總裁申元慶表示,技術發展的大趨勢是“分久必合,合久必分”循環往復的波動,近十年來云計算的發展將算力、存儲、帶寬全部集中在中央部分&…

智能音箱 之 音頻通路質量--測試與參數

一、概述 當將語音識別算法接入到設備時,務必要保證設備的音頻通路具有足夠的質量。因此對設備進行音頻測試,以評估能夠影響語音識別性能的音頻前端的音頻參數。如下要點對語音識別至關重要: 自然聲音合適的增益良好的信噪比一致的響應&…

關于Linux路由表的route命令

轉自:http://www.cnblogs.com/gunl/archive/2010/09/14/1826234.html 查看 Linux 內核路由表 使用下面的 route 命令可以查看 Linux 內核路由表。 # route Destination Gateway Genmask Flags Metric Ref Use Iface 192.168.0.0 * …

Python學習 - 常用模塊(二)

目錄 一. 常用模塊 - hashlib 二. 常用模塊 - hmac 三. 常用模塊 - logging 四. 常用模塊 - re 五. 常用模塊 - requests 六. 常用模塊 - paramiko 一. 常用模塊 - hashlib hash: 一種算法, 3.x里代替了md5模塊和sha模塊, 主要提供 SHA1, SHA224, SHA256, SHA384, SHA512, MD5 …

select函數分析

Select在Socket編程中還是比較重要的,可是對于初學Socket的人來說都不太愛用Select寫程序,他們只是習慣寫諸如connect、accept、recv或recvfrom這樣的阻塞程序(所謂阻塞方式block,顧名思義,就是進程或是線程執行到這些…

UART介紹

1. 概述 UART, Universal Asynchronous Receiver-Transmitter, 通用異步收發器; 串口:在嵌入式里指的是UART口,常用TTL電平即3.3V或者5.0V; COM口:在臺式機上常用的口,DB9那種接口,接口協議只…

mongodb環境安裝

1、mongodb安裝 我采用的是離線安裝, (1)在mongodb的官方網址下載所需要的版本。我下載的是 mongodb-linux-x86_64-ubuntu1604-3.4.5.tgz 。 (2)下載后解壓縮到待安裝目錄,我這里下載在了Downloads目錄…

rabbitmq隊列的exclusive,durability,auto-delete屬性以及消息可靠傳輸設計

非集群下,簡單的說:- 如果是excl,則設置durability沒有意義,因為不管服務器掛了還是客戶端主動/被動斷開了,隊列都會自動刪除。- auto-delete,其實可簡單的認為是同理,即使非excl,則…

IIC 總線接口詳細介紹

1. 概述 IIC Inter Integrated-Circuit 總線是PHLIPS公司推出的一種串行總線,是具備多主機系統所需的包括總線裁決和高低速器件同步功能的高性能串行總線,它支持多主控(multimastering),其中任何能夠進行發送和接收的設備都可以成為主總線。…

DMA數據傳輸過程

DMA方式具有如下特點:1、 外部設備的輸入輸出請求直接發給主儲存器。主存儲器既可以被CPU訪問,也可以被外圍設備訪問。因此,在主存儲器中通常要有一個存儲管理部件來為各種訪問主存儲器的申請排隊,一般計算機系統把外圍設備的訪問…

Android JNI開發系列(二)HelloWorld

2019獨角獸企業重金招聘Python工程師標準>>> 入門HelloWorld 新建項目 Configure your new project部分選中 Include C Support 復選框 Next 正常填寫所有其他字段并完成向導接下來幾個部分 在向導的Customize C Support 部分,您可以使用謝列選項自定…

sublime text3安裝js提示的插件

今天安裝Sublime Text3的js插件,在網上查了很多資料,為了方便以后看,寫一個安裝插件的總結和方法。 要安裝js相關的插件,就要先安裝一個Package Control(插件管理器)的插件,通過這個插件再去安裝…

SPI接口詳細介紹

1. 概述 SPI Serial Peripheral Interface,是串行外圍設備接口,是一種高速,全雙工,同步的通信總線。常規只占用四根線,節約了芯片管腳,PCB的布局省空間。現在越來越多的芯片集成了這種通信協議&#xff0…

駐扎博客園

今天把之前hexo里的一些文章全部轉移到博客園了,之后就在博客園寫點東西,記錄一些生活的瑣事。為什么要移至博客園呢?其實很簡單,這邊可以和一些同意從事前端的小伙伴一起互動。技術還是需要多討論的,希望之后能多更新…

H.264 Profile、Level、Encoder三張簡圖

H.264有四種畫質級別,分別是BP、EP、MP、HP: 1、BP-Baseline Profile:基本畫質。支持I/P 幀,只支持無交錯(Progressive)和CAVLC;   2、EP-Extended profile:進階畫質。支持I/P/B/SP/SI 幀&…

require.js學習記錄

1、簡介 官方對requirejs的描述:RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be used in other JavaScript environments, like Rhino and Node. Using a modular script loader like RequireJS will impro…

iOS-AFNetworking參數和多文件同時上傳【多文件上傳】

1. 前言 在項目開發中,我們經常需要上傳文件,例如:上傳圖片,上傳各種文件,而有時也需要將參數和多個文件一起上傳,不知道大家的項目中遇到了沒有,我在最近的項目中,就需要這樣的一個…

智能音箱 之 平臺方案簡介

智能音箱,被認為是物聯網時代的入口,在去年成為了各大廠商爭相投入的風口。在當今互聯網時代,它不僅僅是一臺單純的音樂播放器,在其背后支撐的 AI 技術才是整個產品的核心,也是各大公司覬覦物聯網入口的最根本原因。經…

Linux Kconfig及Makefile學習

內核源碼樹的目錄下都有兩個文檔 Kconfig (2.4版本是Config.in)和Makefile。分布到各目錄的Kconfig構成了一個分布式的內核配置數據庫,每個Kconfig分別描述了 所屬目錄源文檔相關的內核配置菜單。在內核配置make menuconfig時,從K…

Linux編程 23 shell編程(結構化條件判斷 命令if -then , if-then ... elif-then ...else,if test)...

一.概述 在上一篇里講到了shell腳本,shell按照命令在腳本中出現的順序依次進行處理,對于順序操作已經足夠了,但許多程序要求對shell腳本中的命令加入一些邏輯流程控制,這樣的命令通常叫做 結構化命令。 1.1 使用if - then語句 --最…