• <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>

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運(yùn)轉(zhuǎn),開(kāi)心的工作
            簡(jiǎn)單、開(kāi)放、平等的公司文化;尊重個(gè)性、自由與個(gè)人價(jià)值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            編寫(xiě)大容量和健壯的服務(wù)器系列—處理IOCP連接關(guān)閉  2007-08-11 14:45

            字號(hào): ? ?

            ?

            ?

            鄧立波 深圳,2007-8

            作者聯(lián)系方式 :

            email: ???????? libodeng@gmail.com

            msn:? ???????? libodeng@gmail.com

            tel:???? ???????? 13510275799

            版權(quán)/著作權(quán)所有 (C) 2007 鄧立波 保留所有權(quán)利

            警告:未經(jīng)作者許可,任何人或組織不得轉(zhuǎn)載,公開(kāi)發(fā)布,拷貝,傳播本文獻(xiàn)的全部或部分

            ??

            及時(shí)監(jiān)測(cè)連接被動(dòng)關(guān)閉

            ?????? 除非有特別要求,否則你應(yīng)該總是對(duì)每個(gè)連接保持一個(gè)掛起的接收 pending io

            (使用 WSARecv 投遞)。如果用戶主動(dòng)關(guān)閉連接,你的 GetQueuedCompletionStatus 調(diào)用將返回成功,但接收到的數(shù)據(jù)長(zhǎng)度為 0 ,你能根據(jù)這點(diǎn)檢測(cè)連接是否已被對(duì)方關(guān)閉。如果連接被重置或者 io 被取消(如果你調(diào)用了 CancelIo 的話), GetQueuedCompletionStatus 將返回失敗,注意這時(shí)還應(yīng)該判斷 GetQueuedCompletionStatus 調(diào)用返回的 lpOverlapped 值,如果該值不為 NULL ,說(shuō)明 iocp 已經(jīng)檢測(cè)到一個(gè)連接已經(jīng)中斷。

            ?

            安全的關(guān)閉連接

            ?????? 很多人寫(xiě)的服務(wù)器網(wǎng)絡(luò)庫(kù)有一個(gè)難以接受的缺陷(包括我曾就職公司的一些同事),當(dāng)服務(wù)器程序主動(dòng)關(guān)閉連接時(shí),剛發(fā)往客戶端的包有時(shí)出現(xiàn)丟失,這時(shí)他們推薦的方式往往是發(fā)送數(shù)據(jù)后等待幾秒再關(guān)閉連接。豪無(wú)疑問(wèn),這是一種笨拙的實(shí)現(xiàn)方式,他們遇到的問(wèn)題根源是什么呢?

            ?????? 在非 IOCP 模式網(wǎng)絡(luò)程序中,你只要簡(jiǎn)單的調(diào)用 closesocket 函數(shù)就可以確保數(shù)據(jù)在操作系統(tǒng)釋放 socket 之前安全到達(dá)對(duì)方,但在 IOCP 模式下,如果調(diào)用 closesocket 時(shí)有未決的 pending IO 將導(dǎo)致 socket 被重置,所以有時(shí)會(huì)出現(xiàn)數(shù)據(jù)丟失。正統(tǒng)的解決方式是使用 shutdown 函數(shù)(指定 SD_SEND 標(biāo)志),注意這時(shí)可能有未完成的發(fā)送 pengding IO ,所以你應(yīng)該監(jiān)測(cè)是否該連接的所有是否已完成(也許你要用一個(gè)計(jì)數(shù)器來(lái)跟蹤這些 pending IO ),僅在所有 send pending IO 完成后調(diào)用 shutdown

            當(dāng)你調(diào)用 shutdown 時(shí),也許數(shù)據(jù)仍然停留在操作系統(tǒng)的緩沖,操作系統(tǒng)將在數(shù)據(jù)發(fā)送完后發(fā)出一個(gè) FIN 包來(lái)啟動(dòng)關(guān)閉進(jìn)程,客戶端接收完數(shù)據(jù)后,將接受到一個(gè) 0 長(zhǎng)度的包,以此判斷連接已關(guān)閉(你寫(xiě)的客戶端肯定有檢測(cè)連接關(guān)閉,不是嗎?),然后調(diào)用 closesocket ,這時(shí)服務(wù)器的 GetQueuedCompletionStatus 將接收到一個(gè)數(shù)據(jù)長(zhǎng)度為 0 的包,這時(shí)你就可以調(diào)用 closesocket ,并釋放相關(guān)連接資源。

            在絕大部分情況下上述的過(guò)程連接能完美的關(guān)閉。如果你特別注重服務(wù)器的安全性和健壯性,可能你還需要做一個(gè)“連接關(guān)閉隊(duì)列”,對(duì)每個(gè)已調(diào)用 shutdown 的連接放到這個(gè)隊(duì)列,然后定時(shí)的對(duì)這個(gè)隊(duì)列掃描,如果一個(gè)連接 5 秒(你也可以自己調(diào)整)還不能關(guān)閉,那么就強(qiáng)制關(guān)閉它。

            ?

            處理大并發(fā)短連接時(shí)如何避免 TIME_WAIT 狀態(tài)

            ?????? 關(guān)于如何避免 TIME_WAIT 這個(gè)問(wèn)題,一直沒(méi)看到有效的處理方式(至少我沒(méi)有), 我將在這里披露一種有效的方式。回到上一段,我們最后調(diào)用了 closesocket 關(guān)閉連接,這時(shí)仍然可能出現(xiàn) TIME_WAIT 狀態(tài),但注意這時(shí)所有的數(shù)據(jù)都已經(jīng)傳輸完畢,因此你可以強(qiáng)制關(guān)閉 socket 避免服務(wù)器連接進(jìn)入 TIME_WAIT (這時(shí)只會(huì)發(fā)出連接重置 RESET 包)

            // 立即關(guān)閉 ( 避免出現(xiàn) TIME_WAIT 狀態(tài) )

            ?????? ?????? LINGER linger = {1,0};

            ?????? ?????? setsockopt(socket, SOL_SOCKET, SO_LINGER,

            ????????????? ?????? (char *)&linger, sizeof(linger));

            ?

            ?

            socket唯一性問(wèn)題

            正常情況下 SOCKET 套結(jié)字值是唯一的,但是操作系統(tǒng)在分配 socket 值時(shí)有隨機(jī)性,最近關(guān)閉的 socket 值可能重新分派給一個(gè)剛剛建立的新的 socket. ,尤其在大并發(fā)短連接的情況下。一個(gè)健壯的服務(wù)器 IOCP 網(wǎng)絡(luò)庫(kù)必須要考慮 socket 唯一性的問(wèn)題,由于 IOCP 的排隊(duì)機(jī)制,意味著當(dāng)你調(diào)用 closesocket 關(guān)閉 socket 后, IOCP 隊(duì)列中可能仍然堆積了該 socket 的一些 I/O completion packet ,而此時(shí),剛關(guān)閉的 socket 值又分派給一個(gè)剛剛建立的 socket ,所以,你必須對(duì) GetQueuedCompletionStatus 獲取到的 I/O completion packet 小心翼翼處理,避免出現(xiàn)數(shù)據(jù)混亂,然而,最好的方式等到所有 I/O completion packet 返回后才調(diào)用 closesocket 關(guān)閉該 socket

            ?
            精品伊人久久大线蕉色首页| 麻豆AV一区二区三区久久| 91麻豆国产精品91久久久| 成人免费网站久久久| 久久精品综合网| 91久久精品国产成人久久| 18禁黄久久久AAA片| 99久久综合狠狠综合久久| 亚洲色欲久久久综合网东京热| 亚洲国产精品婷婷久久| 一本一本久久aa综合精品| 久久久WWW成人免费精品| 99精品久久精品| 综合网日日天干夜夜久久| 久久男人AV资源网站| 久久青青草原综合伊人| 久久亚洲精精品中文字幕| 亚洲国产日韩综合久久精品| 精品久久久无码中文字幕天天| 久久w5ww成w人免费| 伊人久久大香线蕉综合影院首页| 久久久久99精品成人片三人毛片| av无码久久久久不卡免费网站| 日本WV一本一道久久香蕉| 久久综合视频网站| 久久e热在这里只有国产中文精品99 | 久久精品国内一区二区三区| 久久久久亚洲av无码专区| 精品久久久久久中文字幕大豆网| 欧美激情精品久久久久久| 久久国产精品波多野结衣AV| 91精品国产高清久久久久久91| 久久国产精品99久久久久久老狼| 国内精品久久久久久久97牛牛| 浪潮AV色综合久久天堂| 久久精品中文騷妇女内射| 人妻无码αv中文字幕久久琪琪布| 久久精品国产男包| 72种姿势欧美久久久久大黄蕉 | 99久久免费国产精精品| 99久久精品日本一区二区免费|