• <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.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
            純c語言實現的IOCP服務器,網上找了很多都是c++的 [轉帖 2008.10.15 22:48:28] ??
            我頂 字號:

            轉自于:http://hi.baidu.com/netpet/blog/item/bb5ebdb7fd4650f030add1a1.html

            代碼如下,注釋已經全部改成中文

            #include?? <winsock2.h>??
            //#include?? <windows.h>??
            #include?? <stdio.h>??

            #define?? PORT?? 5150??
            #define?? DATA_BUFSIZE?? 8192??
            ???
            typedef?? struct??
            {??
            ??????? OVERLAPPED?? Overlapped;??
            ??????? WSABUF?? DataBuf;??
            ??????? CHAR?? Buffer[DATA_BUFSIZE];??
            ??????? DWORD?? BytesSEND;??
            ??????? DWORD?? BytesRECV;??
            }?? PER_IO_OPERATION_DATA,?? *?? LPPER_IO_OPERATION_DATA;??
            ???
            ???
            typedef?? struct????
            {??
            ??????? SOCKET?? Socket;??
            }?? PER_HANDLE_DATA,?? *?? LPPER_HANDLE_DATA;??
            ???
            ???
            DWORD?? WINAPI?? ServerWorkerThread(LPVOID?? CompletionPortID);??
            ???
            int main(void)??
            {??
            ??????? SOCKADDR_IN?? InternetAddr;??
            ??????? SOCKET?? Listen;??
            ??????? SOCKET?? Accept;??
            ??????? HANDLE?? CompletionPort;??
            ??????? SYSTEM_INFO?? SystemInfo;??
            ??????? LPPER_HANDLE_DATA?? PerHandleData;??
            ??????? LPPER_IO_OPERATION_DATA?? PerIoData;??
            ??????? int?? i;??
            ??????? DWORD?? RecvBytes;??
            ??????? DWORD?? Flags;??
            ??????? DWORD?? ThreadID;??
            ??????? WSADATA?? wsaData;??
            ??????? DWORD?? Ret;??
            ???
            ??????? if?? ((Ret?? =?? WSAStartup(0x0202,?? &wsaData))?? !=?? 0)??
            ??????? {??
            ????????????? printf("WSAStartup失敗了,錯誤信息如下:?? %d\n",?? Ret);??
            ????????????? return;??
            ??????? }??
            ???
            ??????? // 設置一個I/O完成端口.??
            ???
            ??????? if?? ((CompletionPort?? =?? CreateIoCompletionPort(INVALID_HANDLE_VALUE,?? NULL,?? 0,?? 0))?? ==?? NULL)??
            ??????? {??
            ????????????? printf(?? "CreateIoCompletionPort 失敗了,錯誤信息如下:?? %d\n",?? GetLastError());??
            ????????????? return;??
            ??????? }??
            ???
            ??????? // 測試系統中有多少cpu處理器
            ???
            ??????? GetSystemInfo(&SystemInfo);??
            ???
            ??????? //?? 基于系統可用的處理器創建工作線程,為每個處理器創建連個線程??
            ???
            ??????? for(i?? =?? 0;?? i?? <?? SystemInfo.dwNumberOfProcessors?? *?? 2;?? i++)??
            ??????? {??
            ????????????? HANDLE?? ThreadHandle;??
            ???
            ????????????? // 創建一個服務端線程并且傳遞一個完成端口給這個線程.??
            ???
            ????????????? if?? ((ThreadHandle?? =?? CreateThread(NULL,?? 0,?? ServerWorkerThread,?? CompletionPort,??
            ??????????????????? 0,?? &ThreadID))?? ==?? NULL)??
            ????????????? {??
            ??????????????????? printf("CreateThread()發生了如下錯誤: %d\n",?? GetLastError());??
            ??????????????????? return;??
            ????????????? }??
            ????????????? else
            ????????????? {printf("創建了一個完成端口.\n");
            ????????????? }
            ????????????? //?? 關閉 thread句柄
            ????????????? CloseHandle(ThreadHandle);??
            ??????? }??
            ???
            ??????? //?? 創建一個監聽套接字
            ???
            ??????? if?? ((Listen?? =WSASocket(AF_INET,?? SOCK_STREAM,?? 0,?? NULL,0,WSA_FLAG_OVERLAPPED))?? ==?? INVALID_SOCKET)??
            ??????? {??
            ????????????? printf("WSASocket() 發生了如下錯誤: %d\n",?? WSAGetLastError());??
            ????????????? return;??
            ??????? }
            ??????? else????
            ??????? {printf("創建監聽套接字成功\n");}
            ??????? InternetAddr.sin_family?? =?? AF_INET;??
            ??????? InternetAddr.sin_addr.s_addr?? =?? htonl(INADDR_ANY);??
            ??????? InternetAddr.sin_port?? =?? htons(PORT);??
            ???
            ??????? if?? (bind(Listen,?? (PSOCKADDR)?? &InternetAddr,?? sizeof(InternetAddr))?? ==?? SOCKET_ERROR)??
            ??????? {??
            ????????????? printf("bind()端口或IP時發生了如下錯誤: %d\n",?? WSAGetLastError());??
            ????????????? return;??
            ??????? }??
            ??????? else
            ??????? {printf("綁定端口%d成功\n",PORT);}
            ??????? // 準備socket 用來監聽??
            ???
            ??????? if?? (listen(Listen,?? 5)?? ==?? SOCKET_ERROR)??
            ??????? {??
            ????????????? printf("listen() 發生了如下錯誤?? %d\n",?? WSAGetLastError());??
            ????????????? return;??
            ??????? }??
            ???????? else
            ??????? {printf("預處理成功,開始在端口 %d 處監聽...\n",PORT);}
            ??????? //接受連接并且交給完成端口處理
            ???
            ??????? while(TRUE)??
            ??????? {??
            ????????????? if?? ((Accept?? =?? WSAAccept(Listen,?? NULL,?? NULL,?? NULL,?? 0))?? ==?? SOCKET_ERROR)??
            ????????????? {??
            ??????????????????? printf("WSAAccept()?? 發生了如下錯誤:?? %d\n",?? WSAGetLastError());??
            ??????????????????? return;??
            ????????????? }??
            ???
            ????????????? // 創建一個套接字信息結構體去聯系起來socket??
            ????????????? if?? ((PerHandleData?? =?? (LPPER_HANDLE_DATA)?? GlobalAlloc(GPTR,????
            ??????????????????? sizeof(PER_HANDLE_DATA)))?? ==?? NULL)??
            ????????????? {??
            ??????????????????? printf("GlobalAlloc()?? 發生了如下錯誤:?? %d\n",?? GetLastError());??
            ??????????????????? return;??
            ????????????? }??
            ???
            ????????????? // 將接受到的套接字與原始的完成端口聯系起來.??
            ???
            ????????????? printf("號碼為?? %d?? 的socket連接上了\n",?? Accept);??
            ????????????? PerHandleData->Socket?? =?? Accept;??
            ???
            ????????????? if?? (CreateIoCompletionPort((HANDLE)?? Accept,?? CompletionPort,?? (DWORD)?? PerHandleData,??
            ??????????????????? 0)?? ==?? NULL)??
            ????????????? {??
            ??????????????????? printf("CreateIoCompletionPort?? 發生了如下錯誤:?? %d\n",?? GetLastError());??
            ??????????????????? return;??
            ????????????? }??
            ???
            ????????????? //?? 創建每一個I/O 套接字信息結構體去和下面被調用的 to?? associate?? with?? the????
            ????????????? //?? WSARecv 連接.??
            ???
            ????????????? if?? ((PerIoData?? =?? (LPPER_IO_OPERATION_DATA)?? GlobalAlloc(GPTR,???????????????????? sizeof(PER_IO_OPERATION_DATA)))?? ==?? NULL)??
            ????????????? {??
            ??????????????????? printf("GlobalAlloc() 發生了如下錯誤: %d\n",?? GetLastError());??
            ??????????????????? return;??
            ????????????? }??
            ????????????? else{printf("接收了一個連接\n");}
            ????????????? ZeroMemory(&(PerIoData->Overlapped),?? sizeof(OVERLAPPED));??
            ????????????? PerIoData->BytesSEND?? =?? 0;??
            ????????????? PerIoData->BytesRECV?? =?? 0;??
            ????????????? PerIoData->DataBuf.len?? =?? DATA_BUFSIZE;??
            ????????????? PerIoData->DataBuf.buf?? =?? PerIoData->Buffer;??
            ???
            ????????????? Flags?? =?? 0;??
            ????????????? if?? (WSARecv(Accept,?? &(PerIoData->DataBuf),?? 1,?? &RecvBytes,?? &Flags,??
            ??????????????????? &(PerIoData->Overlapped),?? NULL)?? ==?? SOCKET_ERROR)??
            ????????????? {??
            ??????????????????? if?? (WSAGetLastError()?? !=?? ERROR_IO_PENDING)??
            ??????????????????? {??
            ????????????????????????? printf("WSARecv() 發生了如下錯誤: %d\n",?? WSAGetLastError());??
            ????????????????????????? return;??
            ??????????????????? }??
            ????????????? }??
            ??????? }??
            }??
            ???
            DWORD?? WINAPI?? ServerWorkerThread(LPVOID?? CompletionPortID)??
            {??
            ??????? HANDLE?? CompletionPort?? =?? (HANDLE)?? CompletionPortID;??
            ??????? DWORD?? BytesTransferred;??
            ??????? LPOVERLAPPED?? Overlapped;??
            ??????? LPPER_HANDLE_DATA?? PerHandleData;??
            ??????? LPPER_IO_OPERATION_DATA?? PerIoData;??
            ??????? DWORD?? SendBytes,?? RecvBytes;??
            ??????? DWORD?? Flags;??
            ?????????
            ??????? while(TRUE)??
            ??????? {??
            ???
            ????????????? if?? (GetQueuedCompletionStatus(CompletionPort,?? &BytesTransferred,??
            ??????????????????? (LPDWORD)&PerHandleData,?? (LPOVERLAPPED?? *)?? &PerIoData,?? INFINITE)?? ==?? 0)??
            ????????????? {??
            ??????????????????? printf("GetQueuedCompletionStatus?? 發生了如下錯誤: %d\n",?? GetLastError());??
            ??????????????????? return?? 0;??
            ????????????? }??
            ???
            ????????????? //首先檢查一下去套接字看是否在上發生了錯誤并且如果發生了錯誤就關閉套接
            ????????????? //字并且清除與套接字連接的 SOCKET_INFORMATION結構信息體
            ????????????? if?? (BytesTransferred?? ==?? 0)??
            ????????????? {??
            ??????????????????? printf("正在關閉socket?? %d\n",?? PerHandleData->Socket);??
            ???
            ??????????????????? if?? (closesocket(PerHandleData->Socket)?? ==?? SOCKET_ERROR)??
            ??????????????????? {??
            ????????????????????????? printf("closesocket()?? 發生了如下錯誤: %d\n",?? WSAGetLastError());??
            ????????????????????????? return?? 0;??
            ??????????????????? }??
            ???
            ??????????????????? GlobalFree(PerHandleData);??
            ??????????????????? GlobalFree(PerIoData);??
            ??????????????????? continue;??
            ????????????? }??
            ??? //檢查如果 BytesRECV字段等于0,這就意味著一個 WSARecv調用剛剛完成了所以從完成的WSARecv()調用中
            ??? //用BytesTransferred值更新 BytesRECV字段
            ????????????? if?? (PerIoData->BytesRECV?? ==?? 0)??
            ????????????? {??
            ??????????????????? PerIoData->BytesRECV?? =?? BytesTransferred;??
            ??????????????????? PerIoData->BytesSEND?? =?? 0;??
            ????????????? }??
            ????????????? else??
            ????????????? {??
            ??????????????????? PerIoData->BytesSEND?? +=?? BytesTransferred;??
            ????????????? }??
            ???
            ????????????? if?? (PerIoData->BytesRECV?? >?? PerIoData->BytesSEND)??
            ????????????? {??
            ??? //發布另外一個 WSASend()請求
            ??? //既然WSASend()不是 gauranteed去發送所有字節的請求
            ??? //繼續調用 WSASend()發送直到所有收到的字節被發送
            ???????????????????
            ??????????????????? ZeroMemory(&(PerIoData->Overlapped),?? sizeof(OVERLAPPED));??
            ???
            ??????????????????? PerIoData->DataBuf.buf?? =?? PerIoData->Buffer?? +?? PerIoData->BytesSEND;??
            ??????????????????? PerIoData->DataBuf.len?? =?? PerIoData->BytesRECV?? -?? PerIoData->BytesSEND;??
            ???
            ??????????????????? if?? (WSASend(PerHandleData->Socket,?? &(PerIoData->DataBuf),?? 1,?? &SendBytes,?? 0,??
            ????????????????????????? &(PerIoData->Overlapped),?? NULL)?? ==?? SOCKET_ERROR)??
            ??????????????????? {??
            ????????????????????????? if?? (WSAGetLastError()?? !=?? ERROR_IO_PENDING)??
            ????????????????????????? {??
            ??????????????????????????????? printf("WSASend() 發生了如下錯誤:?? %d\n",?? WSAGetLastError());??
            ??????????????????????????????? return?? 0;??
            ????????????????????????? }??
            ??????????????????? }??
            ????????????? }??
            ????????????? else??
            ????????????? {??
            ??????????????????? PerIoData->BytesRECV?? =?? 0;??
            ??? //現在沒有更多的字節發送過去用來post另外一個WSARecv()請求
            ???????????????????
            ??????????????????? Flags?? =?? 0;??
            ??????????????????? ZeroMemory(&(PerIoData->Overlapped),?? sizeof(OVERLAPPED));??
            ???
            ??????????????????? PerIoData->DataBuf.len?? =?? DATA_BUFSIZE;??
            ??????????????????? PerIoData->DataBuf.buf?? =?? PerIoData->Buffer;??
            ???
            ??????????????????? if?? (WSARecv(PerHandleData->Socket,?? &(PerIoData->DataBuf),?? 1,?? &RecvBytes,?? &Flags,??
            ????????????????????????? &(PerIoData->Overlapped),?? NULL)?? ==?? SOCKET_ERROR)??
            ??????????????????? {??
            ????????????????????????? if?? (WSAGetLastError()?? !=?? ERROR_IO_PENDING)??
            ????????????????????????? {??
            ??????????????????????????????? printf("WSARecv() 發生了如下錯誤:?? %d\n",?? WSAGetLastError());??
            ??????????????????????????????? return?? 0;??
            ????????????????????????? }??
            ??????????????????? }??
            ????????????? }??
            ??????? }??
            }??

            久久久久国产精品人妻| 7777久久久国产精品消防器材| 亚洲人成网亚洲欧洲无码久久| 国产亚洲精午夜久久久久久| 国产69精品久久久久99| 香蕉久久AⅤ一区二区三区| 要久久爱在线免费观看| 色偷偷偷久久伊人大杳蕉| 久久精品国产99国产精偷| 99久久精品九九亚洲精品| 久久综合九色综合网站| 色综合久久天天综合| 久久夜色精品国产亚洲| 蜜桃麻豆WWW久久囤产精品| 亚洲日本va中文字幕久久| 亚洲精品无码久久千人斩| 久久久久亚洲av无码专区| 亚洲国产高清精品线久久| 最新久久免费视频| 亚洲αv久久久噜噜噜噜噜| 久久久久99精品成人片试看| aaa级精品久久久国产片| 99久久国产亚洲综合精品| 久久久久亚洲AV成人片 | 久久AV高清无码| 青青草国产97免久久费观看| 亚洲人成无码www久久久| 日韩精品久久无码中文字幕| 九九久久99综合一区二区| 久久久久亚洲精品天堂久久久久久| 久久精品国产久精国产思思| 久久免费精品视频| 亚洲人成无码www久久久| 国产精品久久久久久久久| a级毛片无码兔费真人久久| 久久久久av无码免费网| 青青青伊人色综合久久| 亚洲午夜无码久久久久| 国产午夜精品久久久久九九电影| 久久99精品久久久大学生| 久久国产精品二国产精品|