zoukankan      html  css  js  c++  java
  • windows—IOCP

    一、重叠I/O回声服务器端

    服务端:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <WinSock2.h>
      4 
      5 #define BUF_SIZE 1024
      6 void ErrorHandling(char *message);
      7 void CALLBACK ReadCompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD);
      8 void CALLBACK WriteCompRoutine(DWORD, DWORD, LPWSAOVERLAPPED, DWORD);
      9 
     10 typedef struct
     11 {
     12     SOCKET hClntSock;
     13     char buf[BUF_SIZE];
     14     WSABUF wsaBuf;
     15 }PER_IO_DATA, *LPPER_IO_DATA;
     16 
     17 int main(int argc, char *argv[])
     18 {
     19     if (argc != 2) {
     20         printf("Usage : %s <port>
    ", argv[0]);
     21         exit(1);
     22     }
     23 
     24     WSADATA wsaData;
     25     SOCKET hLinSock, hRecvSock;
     26     SOCKADDR_IN lisnAdr, recvAdr;
     27     LPWSAOVERLAPPED lpOvLp;
     28     DWORD recvBytes;
     29     LPPER_IO_DATA hbInfo;
     30     int mode = 1, recvAdrSz, flagInfo = 0;
     31 
     32     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
     33         ErrorHandling("WSAStartup() error.");
     34 
     35     hLinSock = WSASocket(PF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
     36     ioctlsocket(hLinSock, FIONBIO, (u_long*)&mode); // 套接字改成非阻塞的
     37 
     38     memset(&lisnAdr, 0, sizeof(lisnAdr));
     39     lisnAdr.sin_family = AF_INET;
     40     lisnAdr.sin_addr.s_addr = htonl(INADDR_ANY);
     41     lisnAdr.sin_port = htons(atoi(argv[1]));
     42 
     43     if (bind(hLinSock, (SOCKADDR*)&lisnAdr, sizeof(lisnAdr)) == SOCKET_ERROR)
     44         ErrorHandling("bind() error.");
     45     if (listen(hLinSock, 5) == SOCKET_ERROR)
     46         ErrorHandling("listen() error.");
     47     printf("Server start...
    ");
     48     recvAdrSz = sizeof(recvAdr);
     49     while (1)
     50     {
     51         SleepEx(100, TRUE); // 让线程处于等待接收操作系统消息的线程状态
     52         hRecvSock = accept(hLinSock, (SOCKADDR*)&recvAdr, &recvAdrSz);
     53         if (hRecvSock == INVALID_SOCKET){
     54             if (WSAGetLastError() == WSAEWOULDBLOCK)
     55                 continue;
     56             else
     57                 ErrorHandling("accept() error");
     58         }
     59         puts("Client connected...");
     60 
     61         lpOvLp = (LPWSAOVERLAPPED)malloc(sizeof(WSAOVERLAPPED));
     62         memset(lpOvLp, 0, sizeof(lpOvLp));
     63 
     64         hbInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
     65         hbInfo->hClntSock = (DWORD)hRecvSock;
     66         (hbInfo->wsaBuf).buf = hbInfo->buf;
     67         (hbInfo->wsaBuf).len = BUF_SIZE;
     68 
     69         lpOvLp->hEvent = (HANDLE)hbInfo;
     70         WSARecv(hRecvSock, &(hbInfo->wsaBuf), 1, &recvBytes, (LPDWORD)&flagInfo, lpOvLp, ReadCompRoutine);
     71     }
     72     closesocket(hRecvSock);
     73     closesocket(hLinSock);
     74     WSACleanup();
     75     return 0;
     76 }
     77 
     78 void CALLBACK ReadCompRoutine(DWORD dwError, DWORD szRecvBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags)
     79 {
     80     LPPER_IO_DATA hbInfo = (LPPER_IO_DATA)(lpOverlapped->hEvent);
     81     SOCKET hSock = hbInfo->hClntSock;
     82     LPWSABUF bufInfo = &(hbInfo->wsaBuf);
     83     DWORD sentBytes;
     84 
     85     if (szRecvBytes == 0)
     86     {
     87         closesocket(hSock);
     88         free(hbInfo);
     89         free(lpOverlapped);
     90         puts("Client disconnected...");
     91     }
     92     else
     93     {
     94         bufInfo->len = szRecvBytes;
     95         WSASend(hSock, bufInfo, 1, &sentBytes, 0, lpOverlapped, WriteCompRoutine);
     96     }
     97 }
     98 
     99 void CALLBACK WriteCompRoutine(DWORD dwError, DWORD szSendBytes, LPWSAOVERLAPPED lpOverlapped, DWORD flags)
    100 {
    101     LPPER_IO_DATA hbInfo = (LPPER_IO_DATA)(lpOverlapped->hEvent);
    102     SOCKET hSock = hbInfo->hClntSock;
    103     LPWSABUF bufInfo = &(hbInfo->wsaBuf);
    104     DWORD recvBytes;
    105     int flagInfo = 0;
    106     WSARecv(hSock, bufInfo, 1, &recvBytes, (LPDWORD)&flagInfo, lpOverlapped, ReadCompRoutine);
    107 }
    108 
    109 void ErrorHandling(char *message) {
    110     fputs(message, stderr);
    111     fputc('
    ', stderr);
    112 }
    View Code

    二、IOCP回声服务端

    服务端:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <process.h>
      4 #include <WinSock2.h>
      5 #include <windows.h>
      6 
      7 #define BUF_SIZE 128
      8 #define READ 3
      9 #define WRITE 5
     10 void ErrorHandling(char *message);
     11 unsigned int WINAPI EchoThreadMain(LPVOID pComPort);
     12 
     13 typedef struct // socket info
     14 {
     15     SOCKET hClntSock;
     16     SOCKADDR_IN clntAdr;
     17 }PER_HANDLE_DATA, *LPPER_HANDLE_DATA;
     18 
     19 typedef struct // buffer info
     20 {
     21     OVERLAPPED overlapped;
     22     WSABUF wsaBuf;
     23     char buffer[BUF_SIZE];
     24     int rwMode; // read or write
     25 }PER_IO_DATA, *LPPER_IO_DATA;
     26 
     27 int main(int argc, char *argv[])
     28 {
     29     if (argc != 2) {
     30         printf("Usage : %s <port>
    ", argv[0]);
     31         exit(1);
     32     }
     33 
     34     WSADATA wsaData;
     35     HANDLE hComPort;
     36     SYSTEM_INFO sysInfo;
     37     LPPER_IO_DATA ioInfo;
     38     LPPER_HANDLE_DATA handleInfo;
     39 
     40     SOCKET hServSock;
     41     SOCKADDR_IN servAdr;
     42     int recvBytes, i, flags = 0;
     43 
     44     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
     45         ErrorHandling("WSAStartup() error.");
     46 
     47     hComPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
     48     GetSystemInfo(&sysInfo);
     49     for (int i = 0; i < (int)sysInfo.dwNumberOfProcessors; i++)
     50         _beginthreadex(NULL, 0, EchoThreadMain, (LPVOID)hComPort, 0, NULL);
     51 
     52     hServSock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
     53     memset(&servAdr, 0, sizeof(servAdr));
     54     servAdr.sin_family = AF_INET;
     55     servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
     56     servAdr.sin_port = htons(atoi(argv[1]));
     57 
     58     bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr));
     59     listen(hServSock, 5);
     60 
     61     puts("Server start...");
     62     while (1){
     63         SOCKET hClntSock;
     64         SOCKADDR_IN clntAdr;
     65         int addrLen = sizeof(clntAdr);
     66 
     67         hClntSock = accept(hServSock, (SOCKADDR*)&clntAdr, &addrLen);
     68         handleInfo = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
     69         handleInfo->hClntSock = hClntSock;
     70         memcpy(&(handleInfo->clntAdr), &clntAdr, addrLen);
     71 
     72         CreateIoCompletionPort((HANDLE)hClntSock, hComPort, (DWORD)handleInfo, 0);
     73 
     74         ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
     75         memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED));
     76         ioInfo->wsaBuf.len = BUF_SIZE;
     77         ioInfo->wsaBuf.buf = ioInfo->buffer;
     78         ioInfo->rwMode = READ;
     79         WSARecv(handleInfo->hClntSock, &(ioInfo->wsaBuf), 1, (LPDWORD)&recvBytes, (LPDWORD)&flags, &(ioInfo->overlapped), NULL);
     80     }
     81 
     82     WSACleanup();
     83     return 0;
     84 }
     85 
     86 unsigned int WINAPI EchoThreadMain(LPVOID pComPort)
     87 {
     88     HANDLE hComPort = (HANDLE)pComPort;
     89     SOCKET sock;
     90     DWORD bytesTrans;
     91     LPPER_HANDLE_DATA handleInfo;
     92     LPPER_IO_DATA ioInfo;
     93     DWORD flags = 0;
     94     while (1)
     95     {
     96         GetQueuedCompletionStatus(hComPort, &bytesTrans, (LPDWORD)&handleInfo, (LPOVERLAPPED*)&ioInfo, INFINITE);
     97         sock = handleInfo->hClntSock;
     98         if (ioInfo->rwMode == READ)
     99         {
    100             puts("message received!");
    101             if (bytesTrans == 0) // 传输EOF
    102             {
    103                 closesocket(sock);
    104                 free(handleInfo);
    105                 free(ioInfo);
    106                 continue;
    107             }
    108             memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED));
    109             ioInfo->wsaBuf.len = bytesTrans;
    110             ioInfo->rwMode = WRITE;
    111             WSASend(sock, &(ioInfo->wsaBuf), 1, NULL, 0, &(ioInfo->overlapped), NULL);
    112             ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
    113             memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED));
    114             ioInfo->wsaBuf.len = BUF_SIZE;
    115             ioInfo->wsaBuf.buf = ioInfo->buffer;
    116             ioInfo->rwMode = READ;
    117             WSARecv(sock, &(ioInfo->wsaBuf), 1, NULL, &flags, &(ioInfo->overlapped), NULL);
    118         }
    119         else{
    120             puts("message sent");
    121             free(ioInfo);
    122         }
    123     }
    124 }
    125 
    126 void ErrorHandling(char *message) {
    127     fputs(message, stderr);
    128     fputc('
    ', stderr);
    129 }
    View Code
  • 相关阅读:
    PHP数组(数组正则表达式、数组、预定义数组)
    面向对象。OOP三大特征:封装,继承,多态。 这个讲的是【封存】
    uvalive 3938 "Ray, Pass me the dishes!" 线段树 区间合并
    LA4329 Ping pong 树状数组
    HDU 1257 最少拦截系统
    HDU 1260 Tickets
    codeforce 621D
    codeforce 621C Wet Shark and Flowers
    codeforce 621B Wet Shark and Bishops
    codeforce 621A Wet Shark and Odd and Even
  • 原文地址:https://www.cnblogs.com/ACGame/p/10634113.html
Copyright © 2011-2022 走看看