<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 天快黑了 閱讀(1663) 評論(1)  編輯  收藏 所屬分類: Socket
     

    1.       Socket ack (acknowledgement)

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

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

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

    所以為了確保數(shù)據(jù)傳輸?shù)臏蚀_性,我們可以引入ack協(xié)議。有時我們不僅要確保server不但收到了數(shù)據(jù),而且還要保證server成功處理了數(shù)據(jù)。這時,可以等server成功處理完數(shù)據(jù)之后,再給client發(fā)ack

    2.       Socket Keep Alive

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

    所以,如果我們經(jīng)常需要與同一個socket地址發(fā)送/接收數(shù)據(jù)時,應該考慮只創(chuàng)建一次socket,然后一直使用這個socket對象發(fā)送/接收數(shù)據(jù)。

    3.       Heartbeat

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

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

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

    4.       Socket Close

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

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


    當主動一方調(diào)用close(先調(diào)用close)時的狀態(tài)變化:

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

    當被動一方調(diào)用close(后調(diào)用close)時的狀態(tài)變化:

    ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED

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

    我們需要特別注意CLOSE_WAIT 狀態(tài):

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

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

    5.       SO_REUSEADDR Option

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

    socket處于TIME_WAIT 狀態(tài)時,它仍然占用正在使用的IP/PORT。這樣,如果我們的程序(比如socket server)使用了一個固定的IP/PORT,當socket處于TIME_WAIT 狀態(tài)時,程序?qū)⒉荒芰⒓粗貑ⅲ瑫霈F(xiàn)端口占用錯誤。

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

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

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

    Feedback

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

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

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


    網(wǎng)站導航:
     

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

    Copyright © 天快黑了

    主站蜘蛛池模板: 亚洲熟妇av一区二区三区下载| 亚洲AV无码一区二区乱孑伦AS | 四虎影院在线免费播放| 亚洲欧洲自拍拍偷综合| 久草免费在线观看视频| 亚洲无线一二三四区| 免费不卡视频一卡二卡| 亚洲成A人片在线播放器| 黄色成人网站免费无码av| 久久亚洲精品国产精品婷婷| 热99re久久精品精品免费| 在线看亚洲十八禁网站| 免费在线观看黄网站| 91在线视频免费观看| 亚洲Av熟妇高潮30p| 精品久久久久国产免费| 羞羞视频网站免费入口| 亚洲午夜久久久久妓女影院 | 美女被吸屁股免费网站| MM131亚洲国产美女久久| 免费一级毛片无毒不卡| 亚洲国产成人精品青青草原| 女人18一级毛片免费观看| 男人免费视频一区二区在线观看| 亚洲性久久久影院| 99在线免费观看视频| 亚洲国产综合精品中文第一| 免费a级毛片视频| 99精品免费视品| 亚洲沟沟美女亚洲沟沟| 四虎永久成人免费影院域名| a级毛片在线免费看| 亚洲综合色丁香婷婷六月图片| 亚洲国产精品自产在线播放| 久久一本岛在免费线观看2020| 久久久久亚洲国产| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 亚洲熟女www一区二区三区| 亚洲精品一级无码鲁丝片| 久久国产精品免费网站| 亚洲午夜成人精品无码色欲|