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

對一個奇怪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>
            久久资源在线| 欧美在线首页| 欧美日韩亚洲一区二区| 麻豆av一区二区三区| 欧美视频官网| 国精品一区二区三区| 国产精品午夜国产小视频| 欧美亚日韩国产aⅴ精品中极品| 欧美日韩亚洲一区二区| 欧美性一区二区| 国产一区二区三区久久| 亚洲国产免费| 亚洲在线视频网站| 久久国产精品网站| 亚洲电影专区| 日韩香蕉视频| 性欧美videos另类喷潮| 久久五月激情| 欧美日韩一区二区三区在线观看免 | 亚洲一区二区三区四区在线观看| 一区二区欧美在线观看| 久久精品国产精品亚洲精品| 欧美激情视频在线播放 | 亚洲麻豆av| 性亚洲最疯狂xxxx高清| 欧美激情精品久久久| 国产日韩综合| av不卡免费看| 久久综合久色欧美综合狠狠 | 久久亚洲欧洲| 久久亚洲视频| 欧美日韩一区二区国产| 国产欧美精品| 在线视频欧美日韩| 米奇777在线欧美播放| 一片黄亚洲嫩模| 美日韩在线观看| 国产一区二区三区成人欧美日韩在线观看| 在线成人h网| 亚欧成人在线| 在线视频日韩| 欧美激情一区在线| 亚洲国产精品日韩| 久久在线免费| 久久精品国产精品亚洲| 国产视频观看一区| 亚洲午夜精品久久久久久app| 欧美成人一区在线| 久久精品国产欧美亚洲人人爽| 欧美午夜一区二区| 在线一区二区三区四区| 欧美激情一区三区| 久久亚洲午夜电影| 悠悠资源网久久精品| 久久久久国产一区二区三区| 亚洲小说欧美另类婷婷| 欧美色综合天天久久综合精品| 亚洲美女区一区| 亚洲国产精品www| 久久影院亚洲| 亚洲国产精品嫩草影院| 欧美国产视频日韩| 欧美大色视频| 在线性视频日韩欧美| 一区二区欧美日韩| 国产精品久久久久国产a级| 亚洲一区在线直播| 亚洲永久免费观看| 极品av少妇一区二区| 欧美 日韩 国产在线| 欧美成人免费网站| 亚洲天堂成人| 欧美一区二区精品| 亚洲大片在线观看| 亚洲日本乱码在线观看| 国产精品www| 久久久人成影片一区二区三区观看| 欧美一站二站| 亚洲啪啪91| 亚洲一级免费视频| 亚洲成色777777女色窝| 亚洲精一区二区三区| 国产日韩在线看片| 欧美激情欧美激情在线五月| 欧美手机在线视频| 免费永久网站黄欧美| 欧美色精品在线视频| 久久国产福利国产秒拍| 久久久久久国产精品mv| 91久久夜色精品国产九色| 免费一级欧美片在线播放| 毛片av中文字幕一区二区| 亚洲乱码国产乱码精品精可以看| 亚洲另类在线一区| 国产精品永久免费| 久久综合狠狠| 欧美日韩在线三区| 久久精品一区二区三区不卡牛牛 | 亚洲国产精品电影| 一区二区三区国产在线观看| 国外成人性视频| 亚洲美洲欧洲综合国产一区| 国产欧美精品在线播放| 亚洲国产高清自拍| 国产一区视频观看| 一区二区三区高清不卡| 亚洲国产高清自拍| 亚洲欧美日韩另类| 日韩天堂在线观看| 久久国产一区| 香蕉免费一区二区三区在线观看| 欧美国产一区在线| 欧美~级网站不卡| 国产精品主播| 一本久道综合久久精品| 亚洲日本成人网| 久久一区视频| 美女国产一区| 韩国美女久久| 久久激情五月激情| 久久精品成人| 国产精品视频观看| 一级日韩一区在线观看| 一本色道久久综合亚洲精品婷婷| 久久夜色精品国产欧美乱极品| 欧美中文在线免费| 国产精品久久久久aaaa九色| 亚洲精品国产欧美| 日韩一级二级三级| 欧美精品午夜视频| 亚洲人体1000| 一本色道婷婷久久欧美| 欧美日韩精品一二三区| 亚洲精品免费一二三区| 日韩五码在线| 欧美日韩精品是欧美日韩精品| 亚洲精品一区二区三区福利| 亚洲美女毛片| 欧美日韩免费在线| 一区二区三区黄色| 欧美一区二区在线播放| 国产乱码精品一区二区三区av| 午夜久久影院| 鲁大师影院一区二区三区| 尤物在线精品| 欧美不卡激情三级在线观看| 亚洲国产精品欧美一二99| 亚洲日韩欧美一区二区在线| 欧美福利网址| 日韩亚洲成人av在线| 亚洲一区免费观看| 国产女主播视频一区二区| 在线播放不卡| 欧美激情bt| 国产精品无码永久免费888| 精品动漫av| 国产精品久久久久av| av成人激情| 亚洲欧美一区二区激情| 国产精品一区二区黑丝| 欧美自拍偷拍| 欧美激情一二三区| 宅男噜噜噜66国产日韩在线观看| 国产精品久久久久久久久免费桃花| 亚洲综合三区| 欧美成人嫩草网站| 这里只有视频精品| 国产亚洲欧美在线| 欧美成人日本| 亚洲免费在线看| 欧美大秀在线观看| 亚洲欧美卡通另类91av| 欲色影视综合吧| 欧美视频在线播放| 久久国产加勒比精品无码| 亚洲人成艺术| 久久九九国产精品| 一区二区三区免费看| 国外成人在线| 欧美性天天影院| 你懂的视频欧美| 午夜精品一区二区三区在线| 亚洲黑丝在线| 久久婷婷麻豆| 午夜在线观看免费一区| 99这里只有精品| 亚洲第一毛片| 国产一区在线视频| 国产精品国产三级国产普通话蜜臀| 老司机亚洲精品| 欧美综合国产| 亚洲综合日韩在线| 洋洋av久久久久久久一区| 亚洲第一视频网站| 久久综合一区二区三区| 欧美专区在线观看一区| 亚洲调教视频在线观看| 99re在线精品| 日韩一区二区精品| 日韩一级在线观看|