• 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
  • 相关阅读:
    Git撤销commit消息保留修改
    switchysharp设置
    Windows10下的docker安装与入门 (三) 创建自己的docker镜像并且在容器中运行它
    Windows10下的docker安装与入门 (二)使用docker引擎在容器中运行镜像
    Windows10下的docker安装与入门 (一)使用docker toolbox安装docker
    semver(Semantic Versioning)
    conda install mingw libpython
    下载 安装MYsql 服务器
    .NET(c#) 移动APP开发平台
    .NET(c#) 移动APP开发平台
  • 原文地址:https://www.cnblogs.com/ACGame/p/10634113.html
Copyright © 2020-2023  润新知