iocp是一整套高效能的io操作非同步模型,可以用在檔案操作也可以用在網路socket操作上面。當用在網路socket上時,在伺服器端主要配合aceeptex wsasend wsasendto來使用,在客戶機端主要配合connectex wsarecv和wsarecvfrom來使用。這幾天用iocp模型模仿ipmsg軟體時有一些感觸,分享如下:(這裡沒有具體的使用常識,這部分請參考《windows網路程式設計2nd》或者相關網路資料)
一、單句柄資料和單io資料
這部分的術語不是很明白如何而來,只是根據windows網路程式設計一書的中文翻譯而來。
二、acceptex函式
我在這個函式上卡殼了很長時間,他第三個函式表示乙個完成acceptex操作後用來接收資料的乙個緩衝,第四個引數表示乙個緩衝的大小,然後四個函式分別表示本地、遠端位址結構的長度。如果你只想做accept操作而不想在這裡做接收資料的動作那麼把第四個引數設為0即可。但是容易在這裡犯錯的是,如果你認為既然不要接收資料那麼把第三個引數設定為null那麼這次投遞永遠不可能完成,並且所有的返回值wsagetlasterror都會看上去非常正確,這很不幸。即使你不想接收任何資料你也不能把表示緩衝區的引數設為0,而要至少設定乙個長度為兩個位址結構長度加上32的長度才行,如果不到那個長度那麼等著在delete的時候報執行時錯誤吧!後面兩個表示位址結構長度的引數都必須設定成位址結構長度加上16位元組。如果你打算從緩衝裡取出那兩個位址結構,那麼切記在每個位址結構後面都有16位元組的資料塊,這兩塊資料到底是什麼我也不知道,也沒有任何資料給我解釋包括msdn,相當崩潰!
三、connectex函式
基本上這個函式至少從表面上沒有acceptex函式那些龜毛和詭異的東西,但是你認為這跟wsarecv之類api一樣直接簡單你就又錯了。你會發現按照普通的方法呼叫以後呼叫wsagetlasterror返回的是10022錯誤,而不是wsa_io_pending,又崩潰了吧?還好,這次msdn給了你一小行解釋,說the parameter s is an unbound or a listening socket,還是詭異兩個字connect操作幹嘛要繫結?不知道,沒人給解釋,那繫結就對了,那麼綁哪個?最好把你的位址結構像下面這樣設定
sockaddr_in temp;
temp.sin_family = af_inet;
temp.sin_port = htons(0);
temp.sin_addr.s_addr = htonl(addr_any);
四、wsarecvfrom和wsasendto
這兩個函式沒什麼詭異的地方,只有乙個細節,由於這兩個函式都是在udp裡用,所以有個位址結構引數,wsarecvfrom的位址結構api會自己抓取可以在堆疊上分配,而wsasendto的位址結構api不會自己抓取所以需要你用new在堆上分配,在完成以後再delete掉。
另外還有就是基於udp的iocp在win2k上可能有些問題,這個在google大神上很容易找到,比如說你打個wsarecvfrom就能在第一頁看到,在winxp上則沒有什麼問題。
仔細玩了兩天iocp以後發現,細節很重要,無論是看書還是msdn等等英文資料,不要錯過任何乙個單詞,每錯過乙個單詞就多乙個可能讓你在某個地方多除錯乙個小時甚至更多~
ps上次一篇寫了兩個小時的比較幾種socket模型的文章被csdn吃掉了,祈禱這篇不會再被吃(雙手合十ing xd)
關於Socket和IOCP的一些值得注意的地方
關於socket和iocp的一些值得注意的地方 關於socket和iocp的一些值得注意的地方收藏 iocp是一整套高效能的io操作非同步模型,可以用在檔案操作也可以用在網路socket操作上面。當用在網路socket上時,在伺服器端主要配合aceeptex wsasend wsasendto來使用...
關於Socket和IOCP的一些值得注意的地方
iocp是一整套高效能的io操作非同步模型,可以用在檔案操作也可以用在網路socket操作上面。當用在網路socket上時,在伺服器端主要配合aceeptex wsasend wsasendto來使用,在客戶機端主要配合connectex wsarecv和wsarecvfrom來使用。這幾天用ioc...
IOCP中的socket錯誤和資源釋放處理方法
本文出處 前言 錯誤處理和socket釋放,是iocp程式設計中的一大難點.本文試圖就iocp設計中經常遇到的這個難題展開論述並尋找其解決方案,事實上,文中所述的解決方式不僅僅適用於iocp,它同樣適用於epoll等多種伺服器程式設計的網路模型中,前提是 領會這種處理方式的實質.正文 在使用iocp...