admin 发表于 2022-5-28 16:45:55

socket iocp模型

#include "IOCPEchoServ_win.h"
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <winsock2.h>
#include <windows.h>

#define BUF_SIZE 100
#define READ 3
#define WRITE 5

typedef struct //socket info
{
        SOCKET hClntSock;
        SOCKADDR_IN clntAdr;
}PER_HANDLE_DATA,*LPPER_HANDLE_DATA;

typedef struct //buffer info
{
        OVERLAPPED overlapped;
        WSABUF wsaBuf;
        char buffer;
        int rwMode; //READ or WRITE
}PER_IO_DATA,*LPPER_IO_DATA;

//DWORD WINAPI EchoThreadMain(LPVOID CompletionPortIO);
unsigned __stdcall EchoThreadMain(LPVOID CompletionPortIO);

//int main(int argc, char* argv[])
int IOCPEchoServ_win(int argc, char* argv[])
{
        WSADATA wsaData;
        HANDLE hComPort;
        SYSTEM_INFO sysInfo;
        LPPER_IO_DATA ioInfo;
        LPPER_HANDLE_DATA handleInfo;
        SOCKET hServSock;
        SOCKADDR_IN servAdr;
        DWORD recvBytes, i, flags;

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        {
                exit(1);
        }

        hComPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
        GetSystemInfo(&sysInfo);

        for (i = 0; i < sysInfo.dwNumberOfProcessors; i++)
        {
                //_beginthreadex(NULL,0,EchoThreadMain,(LPVOID)hComPort,0,NULL);
                _beginthreadex(NULL, 0, EchoThreadMain, (LPVOID)hComPort, 0, NULL);
        }
               

        hServSock = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
        memset(&servAdr,0,sizeof(servAdr));
        servAdr.sin_family = AF_INET;
        servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
        servAdr.sin_port = htons(atoi("9000"));

        bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr));
        listen(hServSock,5);

        while (1)
        {
                SOCKET hClntSock;
                SOCKADDR_IN clntAdr;
                int addLen = sizeof(clntAdr);

                hClntSock = accept(hServSock,(SOCKADDR*)&clntAdr,&addLen);
                handleInfo = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
                handleInfo->hClntSock = hClntSock;

                memcpy(&(handleInfo->clntAdr),&clntAdr,addLen);

                CreateIoCompletionPort((HANDLE)hClntSock,hComPort,(DWORD)handleInfo,0);

                ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
                memset(&(ioInfo->overlapped),0,sizeof(OVERLAPPED));
                ioInfo->wsaBuf.len = BUF_SIZE;
                ioInfo->wsaBuf.buf = ioInfo->buffer;
                ioInfo->rwMode = READ;

                WSARecv(handleInfo->hClntSock,&(ioInfo->wsaBuf),1,&recvBytes,&flags,&(ioInfo->overlapped),NULL);

        }

        return 0;
}

//DWORD WINAPI EchoThreadMain(LPVOID pComPort)
unsigned __stdcall EchoThreadMain(LPVOID pComPort)
{
        HANDLE hComPort = (HANDLE)pComPort;
        SOCKET sock;
        DWORD bytesTrans;
        LPPER_HANDLE_DATA handleInfo;
        LPPER_IO_DATA ioInfo;
        DWORD flags = 0;

        while(1)
        {
                //GetQueuedCompletionStatus(hComPort,&bytesTrans,(LPDWORD)&handleInfo,(LPOVERLAPPED*)&ioInfo,INFINITE);
                GetQueuedCompletionStatus(hComPort, &bytesTrans, (PULONG_PTR)&handleInfo, (LPOVERLAPPED*)&ioInfo, INFINITE);
               
                sock = handleInfo->hClntSock;

                if (ioInfo->rwMode == READ)
                {
                        puts("message received!");
                        if (bytesTrans == 0)
                        {
                                closesocket(sock);
                                free(handleInfo);
                                free(ioInfo);
                                continue;
                        }

                        memset(&(ioInfo->overlapped),0,sizeof(OVERLAPPED));
                        ioInfo->wsaBuf.len = bytesTrans;
                        ioInfo->rwMode = WRITE;
                        WSASend(sock,&(ioInfo->wsaBuf),1,NULL,0,&(ioInfo->overlapped),NULL);

                        ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
                        memset(&(ioInfo->overlapped),0,sizeof(OVERLAPPED));
                        ioInfo->wsaBuf.len = BUF_SIZE;
                        ioInfo->wsaBuf.buf = ioInfo->buffer;
                        ioInfo->rwMode = READ;
                        WSARecv(sock,&(ioInfo->wsaBuf),1,NULL,&flags,&(ioInfo->overlapped),NULL);
                }
                else
                {
                        puts("message sent!");
                        free(ioInfo);
                }


        }
}
页: [1]
查看完整版本: socket iocp模型