青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

對一個奇怪SOCKET問題的研究

   今天測試網絡服務程序時發現這樣一個現象:客戶端登錄到服務器,服務器如果驗證發現用戶名不存在,就返回客戶端錯誤信息,并斷開與客戶端的連接。但是實際測試時卻發現客戶端并沒有接收到用戶名不存在的錯誤信息,并且明明服務器端關閉了連接,甚至停止了服務,但是客戶端仍然顯示是連接狀態。

   調試,發現在斷開連接操作之前(即CLOSE SOCKET之前),加斷點或者寫LOG或者SLEEP幾毫秒后,客戶端都可接收到錯誤信息,并成功斷開。于是分析覺得問題可能出在SOCKET的IO處理上,可能SOCKET IO中的數據沒有足夠的時間完全發送,SOCKET就被關閉了。

   仔細檢查代碼發現CLOSE SOCKET前做了這樣的操作:

LINGER lingerStruct;
lingerStruct.l_onoff  = 1;    
lingerStruct.l_linger = 0;
setsockopt( IoSocket, SOL_SOCKET, SO_LINGER,    (char *)&lingerStruct, sizeof(lingerStruct) );
CancelIo((HANDLE) IoSocket);
closesocket( IoSocket );
   
   在MSDN中查找setsockeopt關于LINGER的解釋如下:

Setting the SO_DONTLINGER option prevents blocking on member function Close while waiting for unsent data to be sent. Setting this option is equivalent to setting SO_LINGER with l_onoff set to 0.

    若設置了SO_LINGER,并設置了零超時間隔,則closesocket()不被阻塞立即執行,不論是否有排隊數據未發送或未被確認。這種關閉方式稱為“強制”或“失效”關閉,因為套接口的虛電路立即被復位,且丟失了未發送的數據。在遠端的recv()調用將以WSAECONNRESET出錯。
   若設置了SO_LINGER并確定了非零的超時間隔,則closesocket()調用阻塞進程,直到所剩數據發送完畢或超時。這種關閉稱為“優雅的”關閉。請注意如果套接口置為非阻塞且SO_LINGER設為非零超時,則closesocket()調用將以WSAEWOULDBLOCK錯誤返回。
   若在一個流類套接口上設置了SO_DONTLINGER,則closesocket()調用立即返回。但是,如果可能,排隊的數據將在套接口關閉前發送。請注意,在這種情況下WINDOWS套接口實現將在一段不確定的時間內保留套接口以及其他資源,這對于想用所以套接口的應用程序來說有一定影響。
  簡言之,setsockeopt函數使用SO_LINGER規定了斷開SOCKET時處理未發送完的數據的動作。


   查詢UNIX文檔中關于SO_LINGER參數的解釋更加詳細:

   SO_LINGER
   此選項指定函數close對面向連接的協議如何操作(如TCP)。缺省close操作是立即返回,如果有數據殘留在套接口緩沖區中則系統將試著將這些數據發送給對方。

SO_LINGER選項用來改變此缺省設置。使用如下結構:
struct linger {
     int l_onoff; /* 0 = off, nozero = on */
     int l_linger; /* linger time */
};

有下列三種情況:

  1. l_onoff為0,則該選項關閉,l_linger的值被忽略,等于缺省情況,close立即返回;
  2. l_onoff為非0,l_linger為0,則套接口關閉時TCP夭折連接,TCP將丟棄保留在套接口發送緩沖區中的任何數據并發送一個RST給對方,而不是通常的四分組終止序列,這避免了TIME_WAIT狀態;
  3. l_onoff 為非0,l_linger為非0,當套接口關閉時內核將拖延一段時間(由l_linger決定)。如果套接口緩沖區中仍殘留數據,進程將處于睡眠狀態,直 到(a)所有數據發送完且被對方確認,之后進行正常的終止序列(描述字訪問計數為0)或(b)延遲時間到。此種情況下,應用程序檢查close的返回值是 非常重要的,如果在數據發送完并被確認前時間到,close將返回EWOULDBLOCK錯誤且套接口發送緩沖區中的任何數據都丟失。close的成功返 回僅告訴我們發送的數據(和FIN)已由對方TCP確認,它并不能告訴我們對方應用進程是否已讀了數據。如果套接口設為非阻塞的,它將不等待close完 成。
l_linger的單位依賴于實現,4.4BSD假設其單位是時鐘滴答(百分之一秒),但Posix.1g規定單位為秒。

   在了解了原理之后,將代碼中的lingerStruct.l_linger 設置為非零值,問題立即被解決。

   這里把這個問題寫出來,希望能夠給大家帶來點啟示。

posted on 2007-11-14 11:45 迷宮の未來 閱讀(3150) 評論(6)  編輯 收藏 引用

評論

# re: 關閉SOCKET時需注意的問題[未登錄] 2007-11-14 15:45 heroboy

shutdown(...) first.  回復  更多評論   

# re: 關閉SOCKET時需注意的問題 2007-11-14 16:12 追夢時代

@heroboy
謝謝,剛測試了shutdown也可以解決問題  回復  更多評論   

# re: 關閉SOCKET時需注意的問題 2007-11-14 16:21 追夢時代

這里貼上MSDN對于shutdown的注意事項,shutdown不管SO_LINGER如何設置都不會堵塞。

The shutdown function is used on all types of sockets to disable reception, transmission, or both.

If the how parameter is SD_RECEIVE, subsequent calls to the recv function on the socket will be disallowed. This has no effect on the lower protocol layers. For TCP sockets, if there is still data queued on the socket waiting to be received, or data arrives subsequently, the connection is reset, since the data cannot be delivered to the user. For UDP sockets, incoming datagrams are accepted and queued. In no case will an ICMP error packet be generated.

If the how parameter is SD_SEND, subsequent calls to the send function are disallowed. For TCP sockets, a FIN will be sent after all data is sent and acknowledged by the receiver.

Setting how to SD_BOTH disables both sends and receives as described above.

The shutdown function does not close the socket. Any resources attached to the socket will not be freed until closesocket is invoked.

To assure that all data is sent and received on a connected socket before it is closed, an application should use shutdown to close connection before calling closesocket. For example, to initiate a graceful disconnect:
1. Call WSAAsyncSelect to register for FD_CLOSE notification.
2. Call shutdown with how=SD_SEND.
When FD_CLOSE received, call recv until zero returned, or SOCKET_ERROR.
3. Call closesocket.

Note The shutdown function does not block regardless of the SO_LINGER setting on the socket.

An application should not rely on being able to reuse a socket after it has been shut down. In particular, a Windows Sockets provider is not required to support the use of connect on a socket that has been shut down.
  回復  更多評論   

# re: 關閉SOCKET時需注意的問題 2007-11-14 16:34 追夢時代

http://hi.baidu.com/developer_chen/blog/item/53208b4594f4bf25cefca322.html
這篇文章描述了如何安全的關閉SOCKET  回復  更多評論   

# re: 對一個奇怪SOCKET問題的研究 2007-12-23 17:21 秦歌

shutdown管用  回復  更多評論   

# re: 對一個奇怪SOCKET問題的研究 2008-01-31 22:00 abettor

默認情況下,linger是保持TIME_WAIT狀態的。
如果設置了linger選項,closesocket的時候就會以粗暴的形式實現。也就是,在斷開連接的三次握手時,一旦接受到了對方的ACK后,發送一個RST就立即清理資源,而并不等待TCP/IP協議棧真的將全部數據發出,更不會等上兩個MSL的TIME_WAIT狀態。這樣的話,也許RST根本就還沒有發送出去,所以對等端意識不到連接已經中斷。  回復  更多評論   

<2007年12月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

導航

統計

常用鏈接

留言簿(10)

隨筆檔案

文章檔案

最新隨筆

搜索

積分與排名

最新隨筆

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久中文欧美| 欧美日韩国产va另类| 久久国产精品久久久| 亚洲一区三区电影在线观看| 亚洲永久免费av| 国产免费成人av| 久久精品99久久香蕉国产色戒| 亚洲中无吗在线| 国产综合亚洲精品一区二| 久久夜色精品国产噜噜av| 久久影视三级福利片| 一区二区日本视频| 亚洲香蕉视频| 在线观看国产欧美| 日韩午夜av在线| 国产日韩av在线播放| 免费成人高清在线视频| 欧美日韩免费看| 久久精品国产69国产精品亚洲| 牛牛精品成人免费视频| 久久三级视频| 免费成人毛片| 国产欧美日韩精品a在线观看| 久久久综合网站| 欧美电影电视剧在线观看| 亚洲一区二区三区视频播放| 久久电影一区| 亚洲夜晚福利在线观看| 久久综合九九| 销魂美女一区二区三区视频在线| 久久久免费精品视频| 亚洲欧美日韩中文播放| 美女视频一区免费观看| 午夜精品福利在线| 欧美波霸影院| 麻豆9191精品国产| 国产精品一二三四| 亚洲久久成人| 91久久精品国产91久久性色| 欧美激情综合色| 亚洲中无吗在线| 欧美伊人久久大香线蕉综合69| 日韩视频在线观看免费| 永久免费毛片在线播放不卡| 亚洲一区二区三区精品在线观看| 亚洲激情国产精品| 久久久午夜精品| 久久国产88| 国产精品一香蕉国产线看观看| 国产精品男女猛烈高潮激情| 国产精品99久久久久久有的能看| 久久久噜久噜久久综合| 欧美淫片网站| 国产精品美女一区二区| 亚洲美女诱惑| 一区二区欧美视频| 欧美经典一区二区三区| 亚洲韩国精品一区| 国产综合久久久久久鬼色| 国产精品qvod| 亚洲视频观看| 亚洲免费视频在线观看| 亚洲综合视频网| 欧美色区777第一页| 亚洲精品国产视频| 日韩一级大片| 欧美日韩成人在线视频| 日韩视频不卡| 亚洲欧美日韩在线综合| 国产精品日韩欧美| 午夜亚洲一区| 乱人伦精品视频在线观看| 伊人精品久久久久7777| 久久综合免费视频影院| 亚洲成人在线网站| 日韩西西人体444www| 欧美日韩国产bt| 亚洲无毛电影| 久久全球大尺度高清视频| 影音先锋一区| 亚洲免费一在线| 韩国精品一区二区三区| 亚洲国产精品久久91精品| 日韩一级片网址| 欧美三级午夜理伦三级中视频| 亚洲午夜91| 久久久久高清| 亚洲人成毛片在线播放女女| 欧美日韩视频在线第一区| 亚洲综合999| 欧美国产日韩a欧美在线观看| 一本色道久久综合狠狠躁篇的优点 | 1204国产成人精品视频| 欧美国产精品劲爆| 亚洲午夜精品| 欧美1区2区| 亚洲欧美综合精品久久成人| 国产一区二区视频在线观看| 免费视频一区二区三区在线观看| 亚洲美女色禁图| 久久久久成人精品免费播放动漫| 亚洲免费精彩视频| 国产日韩欧美一区二区三区四区| 欧美成人精品h版在线观看| 中文一区在线| 亚洲福利视频三区| 欧美一区二区三区四区高清| 亚洲欧洲一二三| 国内视频一区| 欧美日韩一区视频| 美女在线一区二区| 亚洲欧美在线看| 日韩午夜一区| 亚洲在线视频网站| 久久激情视频| 91久久久一线二线三线品牌| 国产精品99免费看| 免费成人av在线看| 欧美一区日韩一区| 中日韩美女免费视频网址在线观看 | 亚洲欧洲av一区二区三区久久| 亚洲国产精品一区二区尤物区| 国产精品麻豆成人av电影艾秋| 欧美+亚洲+精品+三区| 久久av在线| 香蕉久久国产| 亚洲在线视频网站| 一本色道久久综合狠狠躁篇的优点 | 久久福利资源站| 午夜精品久久久久久久男人的天堂 | 欧美日韩中文在线| 欧美国产一区二区三区激情无套| 久久免费观看视频| 久久在线精品| 久久亚洲二区| 久久亚洲一区二区| 久久香蕉国产线看观看av| 久久精品国产第一区二区三区最新章节| 亚洲综合色激情五月| 亚洲午夜影视影院在线观看| 99国产精品久久久久老师| 99热在线精品观看| 一本到12不卡视频在线dvd| 99精品欧美一区二区三区| 亚洲精品日韩在线| 一区二区三区精品| 亚洲午夜羞羞片| 午夜欧美精品| 久久精品国产精品亚洲| 久久久久se| 免费亚洲视频| 欧美日韩一区在线播放| 国产伦精品一区二区三区高清| 国产日韩精品一区二区三区| 国产日韩成人精品| 精品福利电影| 日韩视频在线免费| 亚洲一区精品电影| 久久久久国产精品麻豆ai换脸| 久久综合中文| 亚洲精品久久久一区二区三区| 中日韩在线视频| 欧美在线不卡视频| 欧美成人精品1314www| 国产精品久久久久久av下载红粉| 国产精品久在线观看| 激情综合色综合久久| 日韩视频中文字幕| 欧美在线免费观看视频| 欧美91大片| 一本色道久久88精品综合| 久久超碰97人人做人人爱| 欧美二区在线播放| 国产日韩欧美一区二区三区在线观看 | 欧美成人久久| 国产精品久久久久7777婷婷| 合欧美一区二区三区| 99视频精品| 快播亚洲色图| 亚洲午夜视频在线| 久热精品视频| 美女诱惑一区| 亚洲国产视频直播| 麻豆av福利av久久av| 免费看精品久久片| 蜜臀91精品一区二区三区| 欧美亚洲在线观看| 亚洲欧美日韩国产精品| 亚洲欧美国产视频| 99pao成人国产永久免费视频| 性色av一区二区怡红| 91久久线看在观草草青青| 午夜视频在线观看一区二区| 欧美激情亚洲| 一区二区三区我不卡| 欧美一级欧美一级在线播放| 亚洲日本免费电影| 女同一区二区| 在线看片成人| 久久精品人人做人人综合|