<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Socket Programming Considerations (2)

    Posted on 2010-07-28 09:23 天快黑了 閱讀(1662) 評論(1)  編輯  收藏 所屬分類: Socket
     

    1.       Socket ack (acknowledgement)

    Socket ack是指當socket接收到數據之后,發送一個ack字符串(比如$ACK)socket發送方。這樣,socket發送方可以根據是否收到了ack判斷對方是否收到了數據。

    Socket ack是顯示的在應用程序中加入的一種通訊協議。如果不使用ack,在socket通訊中,可能會丟失數據。

    比如,socket client要連續的給socket server發送100條消息。如果我們在server收到第50條消息的時候,強行killserver。那么查詢client端發送的log,可能client端成功發送了51條。只有當client端發送第52條消息的時候才遇到異常。這樣第51條消息就丟失了。

    所以為了確保數據傳輸的準確性,我們可以引入ack協議。有時我們不僅要確保server不但收到了數據,而且還要保證server成功處理了數據。這時,可以等server成功處理完數據之后,再給clientack

    2.       Socket Keep Alive

    Socket連接像數據庫連接一樣,屬于重量型資源。如果我們頻繁的創建socket、發送/接收數據、關閉socket,那么會有很大一部分時間浪費在socket的創建和關閉上。

    所以,如果我們經常需要與同一個socket地址發送/接收數據時,應該考慮只創建一次socket,然后一直使用這個socket對象發送/接收數據。

    3.       Heartbeat

    通常,我們會設置socketreceive timeout。這樣,如果我們一直打開著socket (keep alive) 而很長時間又沒有數據通訊,socket接收方就會timeout,最終導致打開的連接壞掉。

    如果很長時間沒有數據通訊,防火墻或代理服務器也可能會關閉打開的socket連接。

    所以為了保證打開的socket連接一直可用,如果一段時間沒有數據進行通訊(或指定一個時間間隔),我們可以顯示的發送一個heartbeat消息(比如: $HRT)給對方,從而保證連接不會被異常關閉。

    4.       Socket Close

    每一個socket對象會持有一個socket descriptor (其實就是file descriptor),操作系統對于socket descriptor有一個最大限制。因此當socket不再使用時,一定要記得關閉,即使socket連接失敗或出現異常,只要socket對象不為null,一定要記得關閉。

    下面圖顯示了,當socket關閉時,socket的狀態變化(socket狀態可以通過netstat命令查看)。更詳細的解釋,可以google一下。


    當主動一方調用close(先調用close)時的狀態變化:

    ESTABLISHED -> FIN_WAIT_1-> FIN_WAIT_2 -> TIME_WAIT -> CLOSED

    當被動一方調用close(后調用close)時的狀態變化:

    ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED

    通常,TIME_WAIT 是正常狀態,過一段時間(2MSL, 14分鐘)就會自動消失.

    我們需要特別注意CLOSE_WAIT 狀態:

    1.   如果很長時間才消失,表明socket server處理太慢,很多client已經連接到server,發送完數據并close了。

    2.   如果一直也不消失,表明有socket沒有正常close (對方已經close)

    5.       SO_REUSEADDR Option

    socket主動調用close的時候,從上面可以知道,它最終會進入TIME_WAIT 狀態,需要過14分鐘,才能完全close

    socket處于TIME_WAIT 狀態時,它仍然占用正在使用的IP/PORT。這樣,如果我們的程序(比如socket server)使用了一個固定的IP/PORT,當socket處于TIME_WAIT 狀態時,程序將不能立即重啟,會出現端口占用錯誤。

    Socket提供了一個setReuseAddress()方法,可以設置當socket處于TIME_WAIT 狀態時,是否允許其它進程綁定這個端口。

    如果我們正在開發socket server,一定要記得調用ServerSocket.setReuseAddress(true).

    Client socket也有這個方法,而且有時可能需要指明client連接server時所使用的本地IP/PORT(一般不用指明,系統會隨機選擇一個PORT)。但實際測試,在client socket上設置這個方法在WindowsSolaris下并不起作用。當socket處于TIME_WAIT 狀態時,重啟client仍然出現端口占用錯誤。上網搜索了很長時間,很多人都碰到了這個問題,可能是操作系統底層socket實現問題。因為測試使用C語言開發的socket client,同樣也有這個錯誤。有人說LINUX下好用,還有就是可以嘗試修改tcp_time_wait_interval來減小TIME_WAIT等待時間

    Feedback

    # re: Socket Programming Considerations (2)[未登錄]  回復  更多評論   

    2010-07-28 17:35 by 匿名
    總體來說寫的不錯,看來對socket還是有比較好的理解的。
    關于setReuseAddress,這個還是設置成true比較好,
    但是要做好地址和端口的檢測工作。如果再加上跨平臺
    和多網卡就比較麻煩。

    只有注冊用戶登錄后才能發表評論。


    網站導航:
     

    posts - 5, comments - 25, trackbacks - 0, articles - 1

    Copyright © 天快黑了

    主站蜘蛛池模板: 亚洲乱码无码永久不卡在线| 亚洲欧洲在线观看| 亚洲中文字幕伊人久久无码| 免费国产成人α片| 日韩毛片免费在线观看| 大学生高清一级毛片免费| 国产亚洲成人久久| 亚洲日产韩国一二三四区| 亚洲看片无码在线视频| 无码国产精品一区二区免费模式| 最近免费中文字幕中文高清| 大陆一级毛片免费视频观看| 亚洲а∨天堂久久精品9966| 免费看的成人yellow视频| 亚洲欧洲久久久精品| 亚洲色丰满少妇高潮18p| 国产成人不卡亚洲精品91| 4455永久在线观免费看| 国产亚洲人成网站在线观看不卡| 国产v亚洲v天堂a无| 免费在线中文日本| 狠狠久久永久免费观看| 色欲aⅴ亚洲情无码AV| 卡1卡2卡3卡4卡5免费视频| 国产成人亚洲综合在线| 日韩一卡2卡3卡4卡新区亚洲| 久久精品国产亚洲香蕉| 亚洲人成网站在线观看播放动漫| 一本色道久久综合亚洲精品蜜桃冫| 天堂在线免费观看| 亚洲经典在线中文字幕| 99久热只有精品视频免费观看17| 好男人看视频免费2019中文| 色偷偷亚洲第一综合| 亚洲乳大丰满中文字幕| 可以免费看黄视频的网站| 久久精品国产亚洲av麻豆蜜芽| 免费大片av手机看片高清| 国产免费卡一卡三卡乱码| 亚洲av纯肉无码精品动漫| 久久免费高清视频|