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

            牽著老婆滿街逛

            嚴(yán)以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            IOCP中的socket錯(cuò)誤和資源釋放處理方法

            本文出處:http://blog.csdn.net/sodme
            聲明:本文可以不經(jīng)作者同意任意轉(zhuǎn)載、復(fù)制、傳播,但任何對本文的引用均須保留本文的作者、出處及本行聲明信息!謝謝!

            前言:?
            錯(cuò)誤處理和socket釋放, 是IOCP編程中的一大難點(diǎn). 本文試圖就IOCP設(shè)計(jì)中經(jīng)常遇到的這個(gè)難題展開論述并尋找其解決方案, 事實(shí)上, 文中所述的解決方式不僅僅適用于IOCP, 它同樣適用于EPOLL等多種服務(wù)器編程的網(wǎng)絡(luò)模型中, 前提是: 領(lǐng)會這種處理方式的實(shí)質(zhì).

            正文:
            在使用IOCP開發(fā)時(shí), 大家經(jīng)常遇到的一個(gè)難題是與socket相關(guān)的緩沖區(qū)釋放不當(dāng)帶來的錯(cuò)誤, 這種錯(cuò)誤通常是由于多次對同一個(gè)指針執(zhí)行了delete操作引起的. 比如, 當(dāng)在執(zhí)行wsasend或wsarecv返回了非pending的錯(cuò)誤信息時(shí), 我們就要對此錯(cuò)誤進(jìn)行處理, 通常情況下, 我們會想到執(zhí)行這兩步操作:
            a. 釋放此次操作使用的緩沖區(qū)數(shù)據(jù)(如果不釋放可能造成內(nèi)存泄漏);
            b. 關(guān)閉當(dāng)前操作所使用的socket.
            而另一方面, 我們可能也會在get函數(shù)(GetQueuedCompletionStatus)的處理中, 當(dāng)get函數(shù)返回值為FALSE時(shí)也作這兩步相同的操作.? 此時(shí), 就會造成對同一緩沖區(qū)的重復(fù)釋放, 問題由此產(chǎn)生.

            解決的方法, 可以有這幾種:
            1. 對數(shù)據(jù)緩沖區(qū)使用引用計(jì)數(shù)機(jī)制;
            2. 在clientsock的對象設(shè)計(jì)機(jī)制上使釋放操作線性化.
            關(guān)于這兩種方法, 任何一種如果要詳細(xì)說清, 可能篇幅都會比較長, 筆者并無耐心和精力將每一個(gè)細(xì)節(jié)都一一道來, 在此僅選第2種方案的關(guān)鍵步驟和核心思想來與大家分享.

            由前面對問題的描述可以看出, 造成多次釋放的原因可能是在執(zhí)行收發(fā)操作和GET函數(shù)返回值為FALSE時(shí), 我們重復(fù)執(zhí)行了釋放操作. 很自然地, 我們會想到,? 能不能把這兩次釋放合并成一次釋放,? 這樣不就沒問題了嗎?? yes,? 這個(gè)思路是沒問題的.? 但要想讓這個(gè)思路能變成現(xiàn)實(shí),? 需要在設(shè)計(jì)機(jī)制上對這個(gè)思路進(jìn)行一定的支持.

            首先,? 我們假設(shè), 是在get函數(shù)返回時(shí)統(tǒng)一進(jìn)行相應(yīng)的釋放和關(guān)閉操作.

            如果在執(zhí)行wsasend操作時(shí), 發(fā)生了非pending錯(cuò)誤(io操作正在進(jìn)行中), 而此時(shí)我們?nèi)绻会尫刨Y源, 那至少得讓IOCP在GET返回時(shí)得知這個(gè)錯(cuò)誤和發(fā)生錯(cuò)誤時(shí)的緩沖區(qū)指針. 通知IOCP的方式, 是使用post函數(shù)(PostQueuedCompletionStatus)向IOCP拋一個(gè)特殊標(biāo)志的消息, 這個(gè)特殊標(biāo)志可以通過get函數(shù)的第二個(gè)參數(shù), 即: 傳送字節(jié)數(shù)來表示, 可以選擇任何一個(gè)不可能出現(xiàn)的值, 比如任何一個(gè)跟它的初始值不相等的負(fù)數(shù).? 當(dāng)然, 如果你通過單句柄數(shù)據(jù)或單IO數(shù)據(jù)來傳遞也是可以的. 而發(fā)生錯(cuò)誤的這個(gè)緩沖區(qū)指針, 我們是必須要通過單句柄數(shù)據(jù)或單IO數(shù)據(jù)來傳遞的. 但是, 從整個(gè)緩沖區(qū)的管理機(jī)制上來說, 我不推薦這樣的離散緩沖區(qū)機(jī)制, 我的建議是: 把收發(fā)緩沖區(qū)或數(shù)據(jù)隊(duì)列與相應(yīng)的clientsocket對象相綁定, 釋放操作寫在該對象的析構(gòu)函數(shù)里, 這樣當(dāng)釋放clientsocket對象時(shí)就釋放了這些緩沖區(qū).

            ok, 這樣一來, 在get函數(shù)里, 有三種情況需要執(zhí)行釋放邏輯:
            1. get的返回值為FALSE;
            2. 傳送字節(jié)數(shù)為0;
            3. 接收到剛才我們post的那個(gè)錯(cuò)誤類型消息.

            把釋放操作全放在get函數(shù)里以后, 對釋放操作的處理, 就比較統(tǒng)一了. 當(dāng)然, 為了實(shí)現(xiàn)真正的線性化和元子化, 在釋放操作的最終執(zhí)行邏輯上, 還需要對釋放代碼加鎖以實(shí)現(xiàn)線程互斥(當(dāng)然, 這是在你開了多個(gè)工作者線程的情況下).

            posted on 2006-04-20 18:52 楊粼波 閱讀(887) 評論(0)  編輯 收藏 引用 所屬分類: 網(wǎng)絡(luò)編程

            国产欧美久久久精品影院| 91麻豆国产精品91久久久| 久久精品国产亚洲av水果派 | 日韩精品久久久久久久电影蜜臀| 国产欧美久久久精品影院| 久久丫精品国产亚洲av| 狠狠精品久久久无码中文字幕 | 亚洲精品蜜桃久久久久久| 久久精品国产亚洲AV电影| 久久久久国色AV免费观看| 久久不见久久见免费视频7| 久久精品国产WWW456C0M| 久久久久亚洲Av无码专| 亚洲精品99久久久久中文字幕| 1000部精品久久久久久久久| 一本一道久久a久久精品综合| 久久国产乱子伦精品免费强| 久久人人爽人人爽人人片AV麻烦| 99久久国产热无码精品免费| 综合久久给合久久狠狠狠97色| 香港aa三级久久三级| 久久综合噜噜激激的五月天| 日韩欧美亚洲综合久久| 精品免费久久久久国产一区| 9久久9久久精品| 99久久中文字幕| 精品久久8x国产免费观看| 久久综合国产乱子伦精品免费| 国产精品久久新婚兰兰| 色婷婷久久综合中文久久一本| 91久久精品国产成人久久| 久久99精品国产一区二区三区| 麻豆一区二区99久久久久| 人妻精品久久无码专区精东影业 | 久久精品国产亚洲一区二区| 久久天天躁狠狠躁夜夜96流白浆| 日本欧美久久久久免费播放网| 久久这里只有精品18| 国产精品久久久久久搜索| 狠狠色丁香久久婷婷综合五月| 久久国产乱子伦精品免费强|