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

Prayer

在一般中尋求卓越
posts - 1256, comments - 190, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

CLOSE_WAIT狀態的生成原因[轉]

Posted on 2009-04-01 19:29 Prayer 閱讀(816) 評論(0)  編輯 收藏 引用 所屬分類: SOCKET

CLOSE_WAIT狀態的生成原因
首先我們知道,如果我們的Client程序處于CLOSE_WAIT狀態的話,說明套接字是被動關閉的!

因為如果是Server端主動斷掉當前連接的話,那么雙方關閉這個TCP連接共需要四個packet:

       Server  --->  FIN  --->  Client

       Server  <---  ACK  <---  Client

    這時候Server端處于FIN_WAIT_2狀態;而我們的程序處于CLOSE_WAIT狀態。

       Server  <---  FIN  <---  Client

這時Client發送FIN給Server,Client就置為LAST_ACK狀態。

        Server  --->  ACK  --->  Client

Server回應了ACK,那么Client的套接字才會真正置為CLOSED狀態。

 

我們的程序處于CLOSE_WAIT狀態,而不是LAST_ACK狀態,說明還沒有發FIN給Server,那么可能是在關閉連接之前還有許多數據要發送或者其他事要做,導致沒有發這個FIN packet。

 

原因知道了,那么為什么不發FIN包呢,難道會在關閉己方連接前有那么多事情要做嗎?

elssann舉例說,當對方調用closesocket的時候,我的程序正在調用recv中,這時候有可能對方發送的FIN包我沒有收到,而是由TCP代回了一個ACK包,所以我這邊套接字進入CLOSE_WAIT狀態。

所以他建議在這里判斷recv函數的返回值是否已出錯,是的話就主動closesocket,這樣防止沒有接收到FIN包。

因為前面我們已經設置了recv超時時間為30秒,那么如果真的是超時了,這里收到的錯誤應該是WSAETIMEDOUT,這種情況下也可以主動關閉連接的。

 

還有一個問題,為什么有數千個連接都處于這個狀態呢?難道那段時間內,服務器端總是主動拆除我們的連接嗎?

 

不管怎么樣,我們必須防止類似情況再度發生!

首先,我們要保證原來的端口可以被重用,這可以通過設置SO_REUSEADDR套接字選項做到:


重用本地地址和端口
以前我總是一個端口不行,就換一個新的使用,所以導致讓數千個端口進入CLOSE_WAIT狀態。如果下次還發生這種尷尬狀況,我希望加一個限定,只是當前這個端口處于CLOSE_WAIT狀態!

在調用

sockConnected = socket(AF_INET, SOCK_STREAM, 0);

之后,我們要設置該套接字的選項來重用:

/// 允許重用本地地址和端口:

/// 這樣的好處是,即使socket斷了,調用前面的socket函數也不會占用另一個,而是始終就是一個端口

/// 這樣防止socket始終連接不上,那么按照原來的做法,會不斷地換端口。

int nREUSEADDR = 1;

setsockopt(sockConnected,

              SOL_SOCKET,

              SO_REUSEADDR,

              (const char*)&nREUSEADDR,

              sizeof(int));
 

教科書上是這么說的:這樣,假如服務器關閉或者退出,造成本地地址和端口都處于TIME_WAIT狀態,那么SO_REUSEADDR就顯得非常有用。

也許我們無法避免被凍結在CLOSE_WAIT狀態永遠不出現,但起碼可以保證不會占用新的端口。

其次,我們要設置SO_LINGER套接字選項:

從容關閉還是強行關閉?
LINGER是“拖延”的意思。

默認情況下(Win2k),SO_DONTLINGER套接字選項的是1;SO_LINGER選項是,linger為{l_onoff:0,l_linger:0}。

如果在發送數據的過程中(send()沒有完成,還有數據沒發送)而調用了closesocket(),以前我們一般采取的措施是“從容關閉”:

因為在退出服務或者每次重新建立socket之前,我都會先調用

/// 先將雙向的通訊關閉

     shutdown(sockConnected, SD_BOTH);

     /// 安全起見,每次建立Socket連接前,先把這個舊連接關閉

closesocket(sockConnected);

 

我們這次要這么做:

設置SO_LINGER為零(亦即linger結構中的l_onoff域設為非零,但l_linger為0),便不用擔心closesocket調用進入“鎖定”狀態(等待完成),不論是否有排隊數據未發送或未被確認。這種關閉方式稱為“強行關閉”,因為套接字的虛電路立即被復位,尚未發出的所有數據都會丟失。在遠端的recv()調用都會失敗,并返回WSAECONNRESET錯誤。

在connect成功建立連接之后設置該選項:

linger m_sLinger;

m_sLinger.l_onoff = 1;  // (在closesocket()調用,但是還有數據沒發送完畢的時候容許逗留)

m_sLinger.l_linger = 0; // (容許逗留的時間為0秒)

setsockopt(sockConnected,

         SOL_SOCKET,

         SO_LINGER,

         (const char*)&m_sLinger,

         sizeof(linger));
 

 

總結
也許我們避免不了CLOSE_WAIT狀態凍結的再次出現,但我們會使影響降到最小,希望那個重用套接字選項能夠使得下一次重新建立連接時可以把CLOSE_WAIT狀態踢掉。


我的意思是:當一方關閉連接后,另外一方沒有檢測到,就導致了CLOSE_WAIT的出現,上次我的一個朋友也是這樣,他寫了一個客戶端和 APACHE連接,當APACHE把連接斷掉后,他沒檢測到,出現了CLOSE_WAIT,后來我叫他檢測了這個地方,他添加了調用 closesocket的代碼后,這個問題就消除了。
如果你在關閉連接前還是出現CLOSE_WAIT,建議你取消shutdown的調用,直接兩邊closesocket試試。


另外一個問題:

比如這樣的一個例子:
當客戶端登錄上服務器后,發送身份驗證的請求,服務器收到了數據,對客戶端身份進行驗證,發現密碼錯誤,這時候服務器的一般做法應該是先發送一個密碼錯誤的信息給客戶端,然后把連接斷掉。

如果把
m_sLinger.l_onoff = 1;
m_sLinger.l_linger = 0;
這樣設置后,很多情況下,客戶端根本就收不到密碼錯誤的消息,連接就被斷了。

 


出現CLOSE_WAIT的原因很簡單,就是某一方在網絡連接斷開后,沒有檢測到這個錯誤,沒有執行closesocket,導致了這個狀態的實現,這在TCP/IP協議的狀態變遷圖上可以清楚看到。同時和這個相對應的還有一種叫TIME_WAIT的。

另外,把SOCKET的SO_LINGER設置為0秒拖延(也就是立即關閉)在很多時候是有害處的。
還有,把端口設置為可復用是一種不安全的網絡編程方法。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美午夜精品一区二区三区| 韩日精品中文字幕| 中国日韩欧美久久久久久久久| 国产精品素人视频| 欧美精品免费在线观看| 欧美精品二区| 欧美视频在线观看 亚洲欧| 欧美性猛交xxxx乱大交退制版| 欧美日韩精品中文字幕| 国产精品久久久久久户外露出| 国产乱码精品| 亚洲成色精品| 在线亚洲观看| 久久久久国产精品人| 欧美第一黄网免费网站| 亚洲美女黄网| 午夜在线视频一区二区区别| 久久人人爽人人爽| 欧美麻豆久久久久久中文| 国产精品视频免费| 亚洲人成在线观看| 午夜在线a亚洲v天堂网2018| 女人天堂亚洲aⅴ在线观看| 亚洲日本va午夜在线电影| 亚洲免费观看| 久久激情视频| 欧美体内she精视频在线观看| 国产午夜亚洲精品羞羞网站 | 一区二区三区三区在线| 香蕉成人伊视频在线观看| 欧美成在线观看| 亚洲女与黑人做爰| 欧美极品欧美精品欧美视频| 韩国成人福利片在线播放| 在线视频精品一区| 蜜乳av另类精品一区二区| 一区二区三区www| 欧美国产91| 亚洲盗摄视频| 久久男女视频| 午夜精品免费| 国产精品久久久免费| 日韩特黄影片| 欧美成人a视频| 久久精品国产999大香线蕉| 欧美视频精品在线观看| 亚洲精品视频一区二区三区| 免费黄网站欧美| 久久精品人人做人人综合| 国产精品一区二区久久久久| 国产精品99久久不卡二区| 欧美国产日韩一区二区| 久久天天狠狠| 亚洲国产一区二区三区a毛片 | 久久女同互慰一区二区三区| 亚洲一区二区视频在线| 欧美四级在线| 国产精品一区二区三区四区五区| 一个人看的www久久| 91久久精品美女| 欧美电影免费观看网站| 亚洲激情一区| 亚洲国产一区二区三区青草影视| 牛夜精品久久久久久久99黑人| 亚洲成人资源| 亚洲精品久久久久久一区二区| 欧美国产乱视频| 亚洲精品一二三| 亚洲精品国产精品乱码不99按摩 | 久久大逼视频| 在线电影国产精品| 亚洲二区在线观看| 欧美精品电影在线| 亚洲一区免费在线观看| 亚洲视频网在线直播| 国产精品高潮呻吟久久| 久久av一区| 久久综合五月天婷婷伊人| 亚洲国产精品久久久久婷婷老年| 亚洲电影网站| 国产精品久久久久久妇女6080| 久久成人精品无人区| 久久久久青草大香线综合精品| 亚洲黄网站在线观看| 日韩视频在线你懂得| 国产欧美日韩视频一区二区三区| 久久噜噜亚洲综合| 欧美精品久久久久久久| 亚洲摸下面视频| 久久精品国产一区二区电影| 亚洲人体一区| 午夜国产一区| 亚洲高清在线观看一区| 亚洲人成高清| 国产一区观看| 亚洲免费不卡| 在线日韩中文| 在线综合亚洲| 亚洲激情不卡| 欧美一区免费| 亚洲一二三四久久| 久久男人av资源网站| 亚洲一区在线播放| 美女主播精品视频一二三四| 亚洲欧美一区二区在线观看| 久久亚洲春色中文字幕| 亚洲欧美日韩在线高清直播| 欧美.日韩.国产.一区.二区| 欧美一区二区三区在| 欧美日韩不卡合集视频| 美女91精品| 国产一区二区三区久久精品| 亚洲三级免费电影| 亚洲欧洲在线免费| 久久久久99| 久久久久久久97| 国产精品一区久久久久| 亚洲理伦在线| 亚洲精品美女在线| 亚洲人成亚洲人成在线观看图片| 美女黄色成人网| 久久美女性网| 中国女人久久久| 久久亚洲精选| 久久精品国产精品| 国产精品a久久久久久| 亚洲第一偷拍| 亚洲国产精品第一区二区| 欧美一区二区三区四区在线观看地址 | 在线日韩av永久免费观看| 亚洲一区国产精品| 亚洲天堂偷拍| 欧美日韩视频专区在线播放| 91久久黄色| 一区二区三区国产精华| 欧美精品一区二区三区四区| 欧美激情国产高清| 在线成人免费视频| 久久影院午夜论| 欧美成人激情视频免费观看| 亚洲第一精品电影| 美女视频黄 久久| 91久久国产综合久久蜜月精品| 日韩午夜av| 欧美吻胸吃奶大尺度电影| 亚洲精品乱码久久久久久蜜桃91| 美脚丝袜一区二区三区在线观看 | 欧美制服丝袜| 国产日韩一区二区| 欧美在线观看网站| 久久美女性网| 亚洲高清不卡av| 欧美精品一区三区在线观看| 亚洲国产女人aaa毛片在线| 亚洲激情在线激情| 欧美激情按摩在线| 日韩一区二区精品| 性欧美videos另类喷潮| 国语对白精品一区二区| 久久久夜色精品亚洲| 亚洲大胆美女视频| 一区二区三区日韩精品视频| 国产精品一区二区在线观看不卡| 欧美激情第4页| 亚洲主播在线播放| 国产日韩欧美自拍| 欧美电影资源| 亚洲视频www| 久久夜色精品国产欧美乱| 亚洲精品裸体| 国产午夜久久久久| 噜噜爱69成人精品| 一区二区三区成人| 久久久综合网站| 亚洲调教视频在线观看| 亚洲欧美在线磁力| 美女主播视频一区| 亚洲视频久久| 精品福利免费观看| 亚洲香蕉视频| 亚洲第一在线| 欧美一区在线看| 亚洲区在线播放| 国产精品久久久久毛片大屁完整版| 午夜视频在线观看一区二区| 欧美激情精品久久久久久蜜臀 | 最新国产拍偷乱拍精品 | 欧美精品播放| 久久久成人网| 亚洲一级在线观看| 亚洲国产日日夜夜| 久久免费国产| 欧美一区二区三区免费视频| 亚洲精品一区二区在线| 国产亚洲一区在线| 国产精品蜜臀在线观看| 欧美精品久久久久久久久老牛影院| 久久精品动漫| 性欧美大战久久久久久久久| 日韩视频一区二区|