在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > Linux協(xié)議棧accept和syn隊列問題

            Linux協(xié)議棧accept和syn隊列問題

            作者: 時間:2016-10-08 來源:網(wǎng)絡(luò) 收藏

            環(huán)境:

            本文引用地址:http://www.biyoush.com/article/201610/305659.htm

            Client 通過tcp 連接server,server端只是listen,但是不調(diào)用accept。通過netstat –ant查看兩端的連接情況。

            server端listen,不調(diào)用accept。

            client一直去connect server。

            問題:

            運行一段時間后,為什么server端的ESTABLISHED連接的個數(shù)基本是固定的129個,但是client端的ESTABLISHED連接的個數(shù)卻在不斷增加?

            分析

            Linux內(nèi)核協(xié)議棧為一個tcp連接管理使用兩個隊列,一個是半鏈接隊列(用來保存處于SYN_SENT和SYN_RECV狀態(tài)的請求),一個是accpetd隊列(用來保存處于established狀態(tài),但是應(yīng)用層沒有調(diào)用accept取走的請求)。

            第一個隊列的長度是/proc/sys/net/ipv4/tcp_max_syn_backlog,默認是1024。如果開啟了syncookies,那么基本上沒有限制。

            第二個隊列的長度是/proc/sys/net/core/somaxconn,默認是128,表示最多有129個established鏈接等待accept。(為什么是129?詳見下面的附錄1)。

            現(xiàn)在假設(shè)acceptd隊列已經(jīng)達到129的情況:

            client發(fā)送syn到server。client(SYN_SENT),server(SYN_RECV)

            server端處理流程:tcp_v4_do_rcv--->tcp_rcv_state_process--->tcp_v4_conn_request

            if(sk_acceptq_is_full(sk) inet_csk_reqsk_queue_yong(sk)>1)

            goto drop;

            inet_csk_reqsk_queue_yong(sk)的含義是請求隊列中有多少個握手過程中沒有重傳過的段。

            在第一次的時候,之前的握手過程都沒有重傳過,所以這個syn包server端會直接drop掉,之后client會重傳syn,當(dāng)inet_csk_reqsk_queue_yong(sk) 1,那么這個syn被server端接受。server會回復(fù)synack給client。這樣一來兩邊的狀態(tài)就變?yōu)閏lient(ESTABLISHED), server(SYN_SENT)

            Client收到synack后回復(fù)ack給server。

            server端處理流程: tcp_check_req--->syn_recv_sock-->tcp_v4_syn_recv_sock

            if(sk_acceptq_is_full(sk)

            goto exit_overflow;

            如果server端設(shè)置了sysctl_tcp_abort_on_overflow,那么server會發(fā)送rst給client,并刪除掉這個鏈接;否則server端只是記錄一下LINUX_MIB_LISTENOVERFLOWS(詳見附錄2),然后返回。默認情況下是不會設(shè)置的,server端只是標記連接請求塊的acked標志,之后連接建立定時器,會遍歷半連接表,重新發(fā)送synack,重復(fù)上面的過程(具體的函數(shù)是inet_csk_reqsk_queue_prune),如果重傳次數(shù)超過synack重傳的閥值(/proc/sys/net/ipv4/tcp_synack_retries),會把該連接從半連接鏈表中刪除。

            一次異常問題分析

            Nginx通過FASTCGI協(xié)議連接cgi程序,出現(xiàn)cgi程序read讀取socket內(nèi)容的時候永遠block。通過netstat查看,cgi程序所在的服務(wù)器上顯示連接存在,但是nginx所在的服務(wù)器上顯示不存在該連接。

            下面是原始數(shù)據(jù)圖:

            我們從上面的數(shù)據(jù)流來分析一下:

            出現(xiàn)問題的時候,cgi程序(tcp server端)處理非常慢,導(dǎo)致大量的連接請求放到accept隊列,把accept隊列阻塞。

            148021 nginx(tcp client端) 連接cgi程序,發(fā)送syn

            此時server端accpet隊列已滿,并且inet_csk_reqsk_queue_yong(sk) > 1,server端直接丟棄該數(shù)據(jù)包

            148840 client端等待3秒后,重傳SYN

            此時server端狀態(tài)與之前送變化,仍然丟棄該數(shù)據(jù)包

            150163 client端又等待6秒后,重傳SYN

            此時server端accept隊列仍然是滿的,但是存在了重傳握手的連接請求,server端接受連接請求,并發(fā)送synack給client端(150164)

            150166 client端收到synack,標記本地連接為ESTABLISHED狀態(tài),給server端應(yīng)答ack,connect系統(tǒng)調(diào)用完成。

            Server收到ack后,嘗試將連接放到accept隊列,但是因為accept隊列已滿,所以只是標記連接為acked,并不會將連接移動到accept隊列中,也不會為連接分配sendbuf和recvbuf等資源。

            150167 client端的應(yīng)用程序,檢測到connect系統(tǒng)調(diào)用完成,開始向該連接發(fā)送數(shù)據(jù)。

            Server端收到數(shù)據(jù)包,由于acept隊列仍然是滿的,所以server端處理也只是標記acked,然后返回。

            150225 client端由于沒有收到剛才發(fā)送數(shù)據(jù)的ack,所以會重傳剛才的數(shù)據(jù)包

            150296 同上

            150496 同上

            150920 同上

            151112 server端連接建立定時器生效,遍歷半連接鏈表,發(fā)現(xiàn)剛才acked的連接,重新發(fā)送synack給client端。

            151113 client端收到synack后,根據(jù)ack值,使用SACK算法,只重傳最后一個ack內(nèi)容。

            Server端收到數(shù)據(jù)包,由于accept隊列仍然是滿的,所以server端處理也只是標記acked,然后返回。

            151896 client端等待3秒后,沒有收到對應(yīng)的ack,認為之前的數(shù)據(jù)包也丟失,所以重傳之前的內(nèi)容數(shù)據(jù)包。

            152579 server端連接建立定時器生效,遍歷半連接鏈表,發(fā)現(xiàn)剛才acked的連接,synack重傳次數(shù)在閥值以內(nèi),重新發(fā)送synack給client端。

            152581 cient端收到synack后,根據(jù)ack值,使用SACK算法,只重傳最后一個ack內(nèi)容。

            Server端收到數(shù)據(jù)包,由于accept隊列仍然是滿的,所以server端處理也只是標記acked,然后返回

            153455 client端等待3秒后,沒有收到對應(yīng)的ack,認為之前的數(shù)據(jù)包也丟失,所以重傳之前的內(nèi)容數(shù)據(jù)包。

            155399 server端連接建立定時器生效,遍歷半連接鏈表,發(fā)現(xiàn)剛才acked的連接,synack重傳次數(shù)在閥值以內(nèi),重新發(fā)送synack給client端。

            155400 cient端收到synack后,根據(jù)ack值,使用SACK算法,只重傳最后一個ack內(nèi)容。

            Server端收到數(shù)據(jù)包,由于accept隊列仍然是滿的,所以server端處理也只是標記acked,然后返回。

            156468 client端等待幾秒后,沒有收到對應(yīng)的ack,認為之前的數(shù)據(jù)包也丟失,所以重傳之前的內(nèi)容數(shù)據(jù)包。

            161309 server端連接建立定時器生效,遍歷半連接鏈表,發(fā)現(xiàn)剛才acked的連接,synack重傳次數(shù)在閥值以內(nèi),重新發(fā)送synack給client端。


            上一頁 1 2 下一頁

            關(guān)鍵詞:

            評論


            相關(guān)推薦

            技術(shù)專區(qū)

            關(guān)閉