实现基于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 1024
  8 #define READ 3
  9 #define WRITE 5
 10 
 11 typedef struct  //socket info
 12 {
 13     SOCKET hClntSock;
 14     SOCKADDR_IN clntAdr;
 15 }PER_HANDLE_DATA, *LPPER_HANDLE_DATA;
 16 
 17 typedef struct  //buffer info
 18 {
 19     OVERLAPPED overlapped;
 20     WSABUF wsaBuf;
 21     char buffer[BUF_SIZE];
 22     int rwMode; // READ or WRITE
 23 }PER_IO_DATA, *LPPER_IO_DATA;
 24 
 25 unsigned WINAPI EchoThreadMain(LPVOID CompletionPortIO);
 26 void ErrorHanding(char *msg);
 27 
 28 int main(int argc, char *argv[])
 29 {
 30     WSADATA wsaData;
 31     HANDLE hComPort;
 32     SYSTEM_INFO sysInfo;
 33     LPPER_IO_DATA ioInfo;
 34     LPPER_HANDLE_DATA handleInfo;
 35 
 36     SOCKET hServSock;
 37     SOCKADDR_IN servAdr;
 38     int recvBytes, i, flags = 0;
 39     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
 40         ErrorHanding("WSAStartUp() error!");
 41 
 42     hComPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
 43     GetSystemInfo(&sysInfo);
 44     for (i = 0; i < sysInfo.dwNumberOfProcessors; i++)
 45         _beginthreadex(NULL, 0, EchoThreadMain, (LPVOID)hComPort, 0, NULL);
 46 
 47     hServSock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
 48     memset(&servAdr, 0, sizeof(servAdr));
 49     servAdr.sin_family = AF_INET;
 50     servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
 51     servAdr.sin_port = htons(atoi(argv[1]));
 52 
 53     bind(hServSock, (SOCKADDR *)&servAdr, sizeof(servAdr));
 54     listen(hServSock, 5);
 55 
 56     while (1)
 57     {
 58         SOCKET hClntSock;
 59         SOCKADDR_IN clntAdr;
 60         int addrLen = sizeof(clntAdr);
 61 
 62         hClntSock = accept(hServSock, (SOCKADDR *)&servAdr, &addrLen);
 63         handleInfo = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
 64         handleInfo->hClntSock = hClntSock;
 65         memcpy(&(handleInfo->clntAdr), &clntAdr, addrLen);
 66 
 67         CreateIoCompletionPort((HANDLE)hClntSock, hComPort, (DWORD)handleInfo, 0);
 68 
 69         ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
 70         memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED));
 71         ioInfo->wsaBuf.len = BUF_SIZE;
 72         ioInfo->wsaBuf.buf = ioInfo->buffer;
 73         ioInfo->rwMode = READ;
 74         WSARecv(handleInfo->hClntSock, &(ioInfo->wsaBuf), 1, (LPDWORD)&recvBytes, (LPDWORD)&flags, &(ioInfo->overlapped), NULL);
 75     }
 76     return 0;
 77 } // end of main function
 78 
 79 unsigned WINAPI EchoThreadMain(LPVOID pComPort)
 80 {
 81     HANDLE hComPort = (HANDLE)pComPort;
 82     SOCKET sock;
 83     DWORD bytesTrans;
 84     LPPER_HANDLE_DATA handleInfo;
 85     LPPER_IO_DATA ioInfo;
 86     DWORD flags = 0;
 87 
 88     while (1)
 89     {
 90         GetQueuedCompletionStatus(hComPort, &bytesTrans, (LPDWORD) &handleInfo, (LPOVERLAPPED *) &ioInfo, INFINITE);
 91         sock = handleInfo->hClntSock;
 92 
 93         if (ioInfo->rwMode == READ)
 94         {
 95             puts("message received!");
 96             if (bytesTrans == 0)
 97             {
 98                 closesocket(sock);
 99                 free(handleInfo);
100                 free(ioInfo);
101                 continue;
102             }
103 
104             memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED));
105             ioInfo->wsaBuf.len = bytesTrans;
106             ioInfo->rwMode = WRITE;
107             WSASend(sock, &(ioInfo->wsaBuf), 1, NULL, 0, &(ioInfo->overlapped), NULL);
108             
109             ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
110             memset(&(ioInfo->overlapped), 0, sizeof(OVERLAPPED));
111             ioInfo->wsaBuf.len = BUF_SIZE;
112             ioInfo->wsaBuf.buf = ioInfo->buffer;
113             ioInfo->rwMode = READ;
114             WSARecv(sock, &(ioInfo->wsaBuf), 1, NULL, &flags, &(ioInfo->overlapped), NULL);
115         }
116         else
117         {
118             puts("message sent!");
119             free(ioInfo);
120         }
121     }
122     return 0;
123 }
124 
125 void ErrorHanding(char *msg)
126 {
127     fputs(msg, stderr);
128     fputc('\n', stderr);
129     exit(1);
130 }

 

posted @ 2019-11-15 16:47  wisdomroc  阅读(162)  评论(0编辑  收藏  举报