完成端口(IOCP)--实例

转载地址:

https://blog.csdn.net/wenhong609/article/details/8834534?utm_source=copy

红色字体我遇到的坑

// CP.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include <iostream>
#include <BaseTsd.h>
using namespace std;

#pragma comment(lib, "ws2_32.lib")

#define BUFFER_SIZE 4096
#define PORT 12345

#define OP_READ 1
#define OP_WRITE 2
#define OP_ACCEPT 3

static int index = 0;

HANDLE hCompletion;


typedef struct _PER_HANDLE_DATA
{    
    SOCKET sock;    sockaddr_in si;
}PER_HANDLE_DATA,*PPER_HANDLE_DATA;  
typedef struct _PER_IO_DATA
{    OVERLAPPED overlapped;    
    WSABUF wsabuf;    
    char buffer[BUFFER_SIZE];    
    int operationType;
}PER_IO_DATA,*PPER_IO_DATA;
DWORD WINAPI ServerThread(LPVOID lParam);

int _tmain(int argc, _TCHAR* argv[])
{
    WSADATA wsa;
    WORD  vW = MAKEWORD(2, 2);
    DWORD err = WSAStartup(vW, &wsa);

    if(0 != err)
    {
        cerr << "socket error";
    }

    if(LOBYTE(wsa.wVersion) != 2 || HIBYTE(wsa.wVersion) != 2)
    {
        cerr << "socket error";
    }

    hCompletion = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
    HANDLE h_DoThread = CreateThread(NULL, 0, ServerThread, (LPVOID)hCompletion, 0, 0);

    SOCKET sListen = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in si;
    si.sin_family = AF_INET;
    si.sin_port = htons(PORT);
    si.sin_addr.S_un.S_addr = INADDR_ANY;
    if(bind(sListen, (SOCKADDR *)&si, sizeof(SOCKADDR)) == SOCKET_ERROR)
    {
        cout << "bind error!";
    }
    listen(sListen, 5);

    while (TRUE)
    {
        sockaddr_in RemoteInfo;
        int RemoteLen = sizeof(sockaddr_in);
        SOCKET AcceptClient = accept(sListen, (sockaddr *)&RemoteInfo, &RemoteLen);

        PPER_HANDLE_DATA pPerHandleData = new PER_HANDLE_DATA;
        pPerHandleData->sock = AcceptClient;
        memcpy(&(pPerHandleData->si), &RemoteInfo, sizeof(sockaddr));

        CreateIoCompletionPort((HANDLE)pPerHandleData->sock, hCompletion, (DWORD)pPerHandleData, 0);

        PPER_IO_DATA pPer_IO_Data = new PER_IO_DATA;
        pPer_IO_Data->operationType = OP_READ;

        pPer_IO_Data->wsabuf.buf = pPer_IO_Data->buffer;
        pPer_IO_Data->wsabuf.len = BUFFER_SIZE;
        DWORD dwRecv;
        DWORD dwFlags = 0;
        
        memset(&pPer_IO_Data->overlapped,0,sizeof(pPer_IO_Data->overlapped));
        WSARecv(pPerHandleData->sock, &(pPer_IO_Data->wsabuf), 1, &dwRecv, &dwFlags, &(pPer_IO_Data->overlapped), NULL);
    }

    return 0;
}

DWORD WINAPI ServerThread(LPVOID lParam)
{
    HANDLE hCompletion = (HANDLE)lParam;
    DWORD dwTrans;
    PPER_HANDLE_DATA pPer_Handle_Data;
    PPER_IO_DATA pPer_IO_Data;
    while(TRUE)
    {
        bool bOk= GetQueuedCompletionStatus(hCompletion, &dwTrans, (LPDWORD)&pPer_Handle_Data, (LPOVERLAPPED *)&pPer_IO_Data, INFINITE);
        if(!bOk)
        {
            cout << GetLastError() << endl;
            closesocket(pPer_Handle_Data->sock);

            delete pPer_Handle_Data;
            delete pPer_IO_Data;
            continue;
        }

        if (dwTrans == 0 && pPer_IO_Data->operationType == OP_READ ||
            pPer_IO_Data->operationType == OP_WRITE)
        {
            closesocket(pPer_Handle_Data->sock);

            delete pPer_Handle_Data;
            delete pPer_IO_Data;
            continue;
        }

        switch (pPer_IO_Data->operationType)
        {
            cout << "Switch" << endl;

        case OP_READ:
            {
                pPer_IO_Data->buffer[dwTrans] = '\0';
                cout << pPer_IO_Data->buffer << endl;
                index++;
                cout << index << endl;

                WSABUF wsabuf;
                wsabuf.buf = pPer_IO_Data->buffer;
                wsabuf.len = BUFFER_SIZE;
                pPer_IO_Data->operationType = OP_READ;
                DWORD flags = 0;
                WSARecv(pPer_Handle_Data->sock, &wsabuf, 1, &dwTrans, &flags, &(pPer_IO_Data->overlapped), NULL);
            }
        }
    }
}


//#include <WINSOCK2.H>
//#include <windows.h>
//#include <iostream>
//#include <basetsd.h>
//using namespace std;
//
//#pragma comment(lib,"ws2_32.lib")
//
//#define BUFFER_SIZE 4096
//#define PORT 12345
//
//
//#define  OP_READ 1
//#define  OP_WRITE 2
//#define     OP_ACCEPT 3
//
//static int index=0;
//
//HANDLE hCompletion;
//typedef struct _PER_HANDLE_DATA
//{
//    SOCKET sock;
//    sockaddr_in si;
//}PER_HANDLE_DATA,*PPER_HANDLE_DATA;
//
//
//typedef struct _PER_IO_DATA
//{
//    OVERLAPPED overlapped;
//    WSABUF wsabuf;
//    char buffer[BUFFER_SIZE];
//    int operationType;
//}PER_IO_DATA,*PPER_IO_DATA;
//DWORD WINAPI ServerThread(LPVOID lParam);
//int main()
//{
//    WSADATA wsa;
//    WSAStartup(MAKEWORD(2,2),&wsa);
//
//
//    hCompletion=::CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
//    HANDLE h_DoThread=CreateThread(NULL,0,ServerThread,(LPVOID)hCompletion,0,0);
//
//    SOCKET sListen=socket(AF_INET,SOCK_STREAM,0);
//    sockaddr_in si;
//    si.sin_family=AF_INET;
//    si.sin_port=htons(PORT);
//    si.sin_addr.S_un.S_addr=INADDR_ANY;
//    bind(sListen,(SOCKADDR *)&si,sizeof(SOCKADDR));
//    listen(sListen,5);
//
//    while(TRUE)
//    {
//        sockaddr_in RemoteInfo;
//        int RemoteLen=sizeof(sockaddr_in);
//        SOCKET AcceptClient=accept(sListen,(sockaddr*)&RemoteInfo,&RemoteLen);
//        //每当有新连接时,将为其创建PER_HANDLE_DATA数据和PER_IO_DATA数据。
//        //PER_HANDLE_DATA
//        PPER_HANDLE_DATA pPerHandleData=new PER_HANDLE_DATA();
//        pPerHandleData->sock=AcceptClient;
//        memcpy(&(pPerHandleData->si),&RemoteInfo,sizeof(sockaddr));
//        //将套接字句柄与完成端口相关联
//        CreateIoCompletionPort((HANDLE)pPerHandleData->sock,hCompletion,
//            (DWORD)pPerHandleData,0);
//
//
//        //PER_IO_DATA
//        PPER_IO_DATA pPer_IO_Data=new PER_IO_DATA();
//        pPer_IO_Data->operationType=OP_READ;
//        //WSARecv等函数中,缓冲区必须是WSABUF,下面对WSABUF进行初始化
//
//        pPer_IO_Data->wsabuf.buf=pPer_IO_Data->buffer;
//        pPer_IO_Data->wsabuf.len=BUFFER_SIZE;
//        DWORD dwRecv;
//        DWORD dwFlags=0;
//
//        //
//        memset(&pPer_IO_Data->overlapped,0,sizeof(pPer_IO_Data->overlapped));
//        //投递一个接收请求
//        ::WSARecv(pPerHandleData->sock,&(pPer_IO_Data->wsabuf),
//            1,&dwRecv,&dwFlags,&(pPer_IO_Data->overlapped),NULL);
//
//    }
//
//    return 0;
//}
//
//DWORD WINAPI ServerThread(LPVOID lParam)
//{
//
//    HANDLE hCompletion=(HANDLE)lParam;
//    DWORD dwTrans;
//    PPER_HANDLE_DATA pPer_Handle_Data;
//    PPER_IO_DATA pPer_IO_Data;
//    cout<<"ServerThread"<<endl;
//    while (TRUE)
//    {
//
//        bool bOk=GetQueuedCompletionStatus(hCompletion,&dwTrans,(LPDWORD)&pPer_Handle_Data,(LPOVERLAPPED*)&pPer_IO_Data,INFINITE);
//        if(!bOk)
//        {
//            cout<<GetLastError()<<endl;
//            //在此套接字上有错误发生
//            closesocket(pPer_Handle_Data->sock);
//
//            delete pPer_Handle_Data;
//            delete pPer_IO_Data;
//            continue;
//        }
//
//        //套接字被对方关闭
//        if(dwTrans==0 && pPer_IO_Data->operationType==OP_READ || pPer_IO_Data->operationType==OP_WRITE )
//        {
//            closesocket(pPer_Handle_Data->sock);
//            delete pPer_Handle_Data;
//            delete pPer_IO_Data;
//            continue;
//        }
//
//
//        switch(pPer_IO_Data->operationType)
//        {
//            cout<<"Switch"<<endl;
//        case OP_READ:
//            {
//
//                pPer_IO_Data->buffer[dwTrans]='\0';
//                cout<<pPer_IO_Data->buffer<<endl;
//                index++;
//                cout<<index<<endl;
//
//
//                //继续投递IO操作
//                WSABUF wsabuf;
//                wsabuf.buf=pPer_IO_Data->buffer;
//                wsabuf.len=BUFFER_SIZE;
//                pPer_IO_Data->operationType=OP_READ;
//                DWORD flags=0;
//                WSARecv(pPer_Handle_Data->sock,&wsabuf,1,&dwTrans,&flags,&(pPer_IO_Data->overlapped),NULL);
//
//            }
//        case OP_WRITE:
//            break;
//        case OP_ACCEPT:
//            break;
//        }
//    }
//    return 0;
//}

猜你喜欢

转载自blog.csdn.net/wojiuguowei/article/details/82854584
今日推荐