<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ### IOCP ***** ![](https://img.kancloud.cn/d5/f6/d5f61d2637fda9aec8448e7b32aa4131_868x642.gif) **IOCP**的核心就在于維護一個公共的消息隊列。首先創建2*CPU核心數的線程,作為Worker,初始的時候它們是空閑,被掛起的。然后再開辟一個單獨的線程,來監聽連接請求,每當有連接請求,就accept,并將網絡操作放入消息隊列中。此時,Worker線程排隊從隊列中取出這些操作請求并處理。注意,整個過程中主線程是非常空閑的,完全有能力去執行其他的任務。也就是說,現在我們有一條主線程,若干條Worker線程,還有一條監聽線程。主線程把網絡請求扔給Worker線程去做,自己就可以同步做別的事情,而不用被阻塞掛起,等待外部I/O完成了。而這個公共消息隊列,就叫做”完成端口“,因為它是”完成“網絡操作(屬于外部I/O)之后再通知主線程把數據拿走...大概就是這么個模型 ### 示例代碼 ***** **iocp_s.cpp** ``` #include <winsock2.h> #include <stdio.h> #include <iostream> #pragma comment(lib, "ws2_32.lib") using namespace::std; #define BUF_SIZE 1024 void CALLBACK ReadCompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD); void CALLBACK WriteCompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD); void ErrorHanding(char * message); typedef struct { SOCKET hClntSock; //套接字句柄 char buf[BUF_SIZE]; //緩沖 WSABUF wsaBuf; //緩沖相關信息 }PER_IO_DATA,*LPPER_IO_DATA; int main() { WSADATA wsaData; SOCKET hLisnSock, hRecvSock; SOCKADDR_IN lisnAdr, recvAdr; LPWSAOVERLAPPED lpOvlap; DWORD recvBytes; LPPER_IO_DATA hbInfo; int recvAdrSz; DWORD flagInfo = 0; u_long mode = 1; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)//加載庫并獲取庫信息填至wsaData ErrorHanding("socket start error!"); //參數:協議族,套接字傳輸方式,使用的協議,WSA_PROTOCOL_INFO結構體地址/不需要時傳null,擴展保留參數,套接字屬性信息 hLisnSock = WSASocket(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); //將hLisnSock句柄的套接字I/O模式(FIONBIO)改為mode中指定的形式:非阻塞模式 ioctlsocket(hLisnSock, FIONBIO, &mode); //設置目標地址端口 memset(&lisnAdr, 0, sizeof(lisnAdr)); lisnAdr.sin_family = AF_INET; lisnAdr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); lisnAdr.sin_port = htons(5099); //套接字綁定 if (bind(hLisnSock, (SOCKADDR*)&lisnAdr, sizeof(lisnAdr)) == SOCKET_ERROR) ErrorHanding("socket bind error!"); //設置為監聽模式 if (listen(hLisnSock, 5) == SOCKET_ERROR) ErrorHanding("socket listen error!"); recvAdrSz = sizeof(recvAdr); while (1) { //進入短暫alertable wait 模式,運行ReadCompRoutine、WriteCompRoutine函數 SleepEx(100, TRUE); //非阻塞套接字,需要處理INVALID_SOCKET //返回的新的套接字也是非阻塞的 hRecvSock = accept(hLisnSock, (SOCKADDR*)&recvAdr, &recvAdrSz); if (hRecvSock == INVALID_SOCKET) { //無客戶端連接時,accept返回INVALID_SOCKET,WSAGetLastError()返回WSAEWOULDBLOCK if (WSAGetLastError() == WSAEWOULDBLOCK) continue; else ErrorHanding("accept() error"); } puts("Client connected"); //申請重疊I/O需要使用的結構體變量的內存空間并初始化 //在循環內部申請:每個客戶端需要獨立的WSAOVERLAPPED結構體變量 lpOvlap = (LPWSAOVERLAPPED)malloc(sizeof(WSAOVERLAPPED)); memset(lpOvlap, 0, sizeof(WSAOVERLAPPED)); hbInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA)); hbInfo->hClntSock = (DWORD)hRecvSock; (hbInfo->wsaBuf).buf = hbInfo->buf; (hbInfo->wsaBuf).len = BUF_SIZE; //基于CR的重疊I/O不需要事件對象,故可以用來傳遞其他信息 lpOvlap->hEvent = (HANDLE)hbInfo; //接收第一條信息 WSARecv(hRecvSock, &(hbInfo->wsaBuf), 1, &recvBytes, &flagInfo, lpOvlap, ReadCompRoutine); } closesocket(hRecvSock); closesocket(hLisnSock); WSACleanup(); return 1; } //參數:錯誤信息,實際收發字節數,OVERLAPPED類型對象,調用I/O函數時傳入的特性信息 void CALLBACK ReadCompRoutine(DWORD dwError, DWORD szRecvBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags) { //從lpoverlapped中恢復傳遞的信息 LPPER_IO_DATA hbInfo = (LPPER_IO_DATA)(lpOverlapped->hEvent); SOCKET hSock = hbInfo->hClntSock; LPWSABUF bufInfo = &(hbInfo->wsaBuf); DWORD sentBytes; //接收到EOF,斷開連接 if (szRecvBytes == 0) { closesocket(hSock); free(hbInfo); free(lpOverlapped); puts("Client disconnected"); } else { bufInfo->len = szRecvBytes; //將接收到的信息回傳回去,傳遞完畢執行WriteCompRoutine(): 接收信息 WSASend(hSock, bufInfo, 1, &sentBytes, 0, lpOverlapped, WriteCompRoutine); } } //參數:錯誤信息,實際收發字節數,OVERLAPPED類型對象,調用I/O函數時傳入的特性信息 void CALLBACK WriteCompRoutine(DWORD dwError, DWORD szRecvBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags) { //從lpoverlapped中恢復傳遞的信息 LPPER_IO_DATA hbInfo = (LPPER_IO_DATA)(lpOverlapped->hEvent); SOCKET hSock = hbInfo->hClntSock; LPWSABUF bufInfo = &(hbInfo->wsaBuf); DWORD recvBytes; DWORD flagInfo = 0; //接收數據,接收完畢執行ReadCompRoutine:發送數據 WSARecv(hSock, bufInfo, 1, &recvBytes, &flagInfo, lpOverlapped, ReadCompRoutine); } void ErrorHanding(char * message) { cout << message << endl; exit(1); } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看