• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            大龍的博客

            常用鏈接

            統計

            最新評論

            幾個重要的TCP/IP選項解析(Java Socket)

            1. SO_LINGER / SO_REUSEADDR
                TCP正常的關閉過程如下(四次握手過程):
            (FIN_WAIT_1) A       ---FIN--->       B(CLOSE_WAIT)
            (FIN_WAIT_2) A       <--ACK--       B(CLOSE_WAIT)
              (TIME_WAIT)A        <--FIN----       B(LAST_ACK)
              (TIME_WAIT)A        ---ACK->       B(CLOSED)
                Ø  A端首先發送一個FIN請求給B端,要求關閉,發送后A段的TCP狀態變更為FIN_WAIT_1,接收到FIN請求后B端的TCP狀態變更為CLOSE_WAIT
                Ø  B接收到ACK請求后,B回一個ACK給A端,確認接收到的FIN請求,接收到ACK請求后,A端的TCP狀態變更為為FIN_WAIT_2。
                Ø  B端再發送一個FIN請求給A端,與連接過程的3次握手過程不一樣,這個FIN請求之所以并不是與上一個請求一起發送,之所以如此處理,是因為TCP是雙 通道的,允許在發送ACK請求后,并不馬上發FIN請求,即只關閉A到B端的數據流,仍然允許B端到A端的數據流。這個ACK請求發送之后,B端的TCP 狀態變更為LAST_ACK,A端的狀態變更為TIME_WAIT。
                Ø  A端接收到B端的FIN請求后,再回B端一個ACK信息,對上一個FIN請求進行確認,到此時B端狀態變更為CLOSED,Socket可以關閉。
               除了如上正常的關閉(優雅關閉)之外,TCP還提供了另外一種非優雅的關閉方式RST(Reset)
               (CLOSED) A         ---RST-->      B (CLOSED)
               Ø  A端發送RST狀態之后,TCP進入CLOSED狀態,B端接收到RST后,也即可進入CLOSED狀態。
                在第一種關閉方式上(優雅關閉),非常遺憾,A端在最后發送一個ACK請求后,并不能馬上將該Socket回收,因為A并不能確定B一定能夠接收到這個 ACK請求,因此A端必須對這個Socket維持TIME_WAIT狀態2MSL(MSL=Max Segment Lifetime,取決于操作系統和TCP實現,該值為30秒、60秒或2分鐘)。如果A端是客戶端,這并不會成為問題,但如果A端是服務端,那就很危險 了,如果連接的Socket非常多,而又維持如此多的TIME_WAIT狀態的話,那么有可能會將Socket耗盡(報Too Many Open File)。
                服務端為了解決這個問題,可選擇的方式有三種:
                Ø  保證由客戶端主動發起關閉(即做為B端)
                Ø  關閉的時候使用RST的方式
                Ø  對處于TIME_WAIT狀態的TCP允許重用
                 一般我們當然最好是選擇第一種方式,實在沒有辦法的時候,我們可以使用SO_LINGER選擇第二種方式,使用SO_REUSEADDR選擇第三種方式

            1. public   void  setSoLinger( boolean  on,  int  linger)  throws  SocketException   
            2. public   void  setReuseAddress( boolean  on)  throws  SocketException   

                第一個on表示是否使用SO_LINGER選項,linger(以秒為單位)表示在發RST之前會等待多久,因為一旦發送RST,還在緩沖區中還沒有發送出去的數據就會直接丟棄


            2.TCP_NODELAY
                 對于交互型的應用(譬如telnet),經常存在的情況是客戶端和服務端之間需要頻繁地進行一些小數據交換,譬如telnet可能每敲一個鍵盤都需要將數 據發送到服務端。為了避免這種情況會產生大量小數據包,提出了Nagle算法。Nagle算法要求每次在發送端最后只有一個未被確認的包,因此上一個包發 送出去還沒有接收到響應之前,要求發送的包回先放在緩沖區,接收到響應之后,會將緩沖區中的包合并成一個包發送出去(可以看到,響應回地越快,發送出去的 數據也會越快)。
                 需要注意的是,由Nagle算法要求只能有一個未被確認的包,因此窗口參數會失效,在大數據量傳送的情況下會使網絡吞吐量下降,因此對于大數據量的交互, 應該關閉Nagle算法,Nagle算法比較適合小數據量頻繁交換的情景。我們可以使用TCP_NODELAY關閉Nagle算法。

            1. public   void  setTcpNoDelay( boolean  on)  throws  SocketException  

            3.SO_KEEPALIVE
                 在一個TCP連接建立之后,我們會很奇怪地發現,默認情況下,如果一端異常退出(譬如網絡中斷后一端退出,使地關閉請求另一端無法接收到),TCP的另一 端并不能獲得這種情況,仍然會保持一個半關閉的連接,對于服務端,大量半關閉的連接將會是非常致命的。SO_KEEPALIVE提供了一種手段讓TCP的 一端(通常服務提供者端)可以檢測到這種情況。如果我們設置了SO_KEEPALIVE,TCP在距離上一次TCP包交互2個小時(取決于操作系統和 TCP實現,規范建議不低于2小時)后,會發送一個探測包給另一端,如果接收不到響應,則在75秒后重新發送,連續10次仍然沒有響應,則認為對方已經關 閉,系統會將該連接關閉。一般情況下,如果對方已經關閉,則對方的TCP層會回RST響應回來,這種情況下,同樣會將連接關閉。

            public   void  setKeepAlive( boolean  on)  throws  SocketException 

            posted on 2012-02-09 11:53 大龍 閱讀(666) 評論(0)  編輯 收藏 引用

            香蕉aa三级久久毛片| 久久精品国产亚洲欧美| 久久99精品九九九久久婷婷| 精品国产热久久久福利| 色青青草原桃花久久综合| 久久人人爽人人爽人人片AV不 | 久久99久久99小草精品免视看| 国产精品9999久久久久| 久久亚洲av无码精品浪潮| 中文国产成人精品久久不卡| 国产成人久久精品激情| 久久久久亚洲AV综合波多野结衣| 欧美亚洲国产精品久久高清| 久久精品一区二区国产| 久久久久久久综合狠狠综合| 情人伊人久久综合亚洲| 久久精品无码一区二区WWW| 国产69精品久久久久99| 久久国产乱子伦免费精品| 人妻中文久久久久| 国产精品久久久天天影视香蕉 | 亚洲欧美日韩中文久久| 久久99热这里只有精品国产| 国内精品久久久久久99蜜桃| 人妻无码精品久久亚瑟影视| 久久国产乱子伦精品免费午夜| 国内精品伊人久久久久av一坑 | 久久人人爽人爽人人爽av| 国产精品久久久久久一区二区三区| 亚州日韩精品专区久久久| 青青热久久综合网伊人| 久久99精品久久久久久hb无码 | 亚洲欧美国产精品专区久久| 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 久久久久无码国产精品不卡| 99久久久国产精品免费无卡顿| 色综合久久无码五十路人妻| 无码国内精品久久综合88| 久久综合成人网| 久久综合视频网| 伊人久久大香线蕉无码麻豆|