博客
关于我
iocp的例子 http://www.oschina.net/code/piece_full?code=24178
阅读量:510 次
发布时间:2019-03-07

本文共 5313 字,大约阅读时间需要 17 分钟。

#pragma once#include 
#define IP_SIZE 32#define BUFFER_SIZE 1024#include
#include
enum SOCKET_STATE { ACCEPT = 1, SEND, RECV};typedef struct tagPLEData { SOCKET sSocket; CHAR szClientIP[IP_SIZE]; UINT uiClientPort; /*其他信息*/} PLEDATA, *LPPLEDATA;typedef struct tagIOData { OVERLAPPED oOverlapped; WSABUF wsBuffer; CHAR szBuffer[BUFFER_SIZE]; DWORD dSend; DWORD dRecv; SOCKET_STATE sState;} IOData, *LPIOData;typedef void (*ReadProc)(LPPLEDATA lpData, CHAR * RecvData);class Iocp {public: Iocp(const CHAR * host, UINT port); ~Iocp(); void SetThreadNums(); UINT GetThreadNums(); void SetPort(UINT port); UINT GetPort(); void Close(); static void ServerWorkThread(VOID * _this); void SetReadProc(VOID * lprFun);public: bool ListenEx(UINT backlog); ReadProc lpFun; HANDLE h_ComPlePort; static void AcceptEx(VOID * _this); UINT iThreadNums; bool bIsListen; SOCKADDR_IN m_SockAddr; SOCKET m_ListenSocketID; CHAR m_Host[IP_SIZE]; UINT m_Port;};
#include "Iocp.h"Iocp::Iocp(const CHAR * host, UINT port) {    WSADATA wsaData;    DWORD dwRet = WSAStartup(0x0202, &wsaData);    if (0 != dwRet) {        WSACleanup();        throw 1;    }    m_ListenSocketID = INVALID_SOCKET;    memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN));    memset(m_Host, 0, IP_SIZE);    m_Port = 0;    SYSTEM_INFO mySysInfo;    GetSystemInfo(&mySysInfo);    iThreadNums = mySysInfo.dwNumberOfProcessors * 2 + 1;    bIsListen = true;    strncpy_s(m_Host, host, IP_SIZE - 1);    m_SockAddr.sin_family = AF_INET;    m_SockAddr.sin_addr.s_addr = inet_addr(host);    m_SockAddr.sin_port = htons(port);    m_ListenSocketID = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);    if (m_ListenSocketID == INVALID_SOCKET) {        throw 1;    }    setsockopt(m_ListenSocketID, SOL_SOCKET, SO_REUSEADDR, (const CHAR *) &opt, sizeof(opt));    if (ret != 0) {        throw 1;    }    if (bind(m_ListenSocketID, (const struct sockaddr *) &m_SockAddr, sizeof(struct sockaddr)) == SOCKET_ERROR) {        throw 1;    }    h_ComPlePort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);    if (h_ComPlePort == NULL) {        throw 1;    }    for (DWORD i = 0; i < (mySysInfo.dwNumberOfProcessors * 2 + 1); ++i) {        _beginthread(Iocp::ServerWorkThread, 0, (VOID *) this);    }}Iocp::~Iocp() {    WSACleanup();}BOOL Iocp::ListenEx(UINT backlog) {    if (listen(m_ListenSocketID, backlog) == SOCKET_ERROR) {        return false;    }    if (-1 == _beginthread(Iocp::AcceptEx, 0, (VOID *) this)) {        return false;    }    return true;}void Iocp::AcceptEx(VOID * _this) {    SOCKET acSocket;    DWORD dwRecvBytes;    Iocp * pTemp = (Iocp *) _this;    SOCKADDR_IN sAddr;    UINT uiClientSize = sizeof(sAddr);    while (true) {        acSocket = WSAAccept(pTemp->m_ListenSocketID, (SOCKADDR *) &sAddr, &uiClientSize, NULL, 0);        if (acSocket == SOCKET_ERROR) {            return;        }        LPPLEDATA lpSocketData = (LPPLEDATA) malloc(sizeof(PLEDATA));        if (lpSocketData == NULL) {            return;        }        lpSocketData->sSocket = acSocket;        sprintf(lpSocketData->szClientIP, inet_ntoa(sAddr.sin_addr));        lpSocketData->uiClientPort = sAddr.sin_port;        if (CreateIoCompletionPort((HANDLE) acSocket, pTemp->h_ComPlePort, (ULONG_PTR) lpSocketData, 0) == NULL) {            return;        }        if (pTemp->bIsListen = false) {            break;        }        LPIOData lpIoData = (LPIOData) malloc(sizeof(IOData));        if (lpIoData == NULL) {            return;        }        ZeroMemory(lpIoData->oOverlapped, sizeof(lpIoData->oOverlapped));        lpIoData->dSend = 0;        lpIoData->dRecv = 0;        lpIoData->wsBuffer.len = BUFFER_SIZE;        lpIoData->wsBuffer.buf = lpIoData->szBuffer;        lpIoData->sState = SEND;        if (WSARecv(acSocket, (WSABUF *) lpIoData->wsBuffer, 1, &dwRecvBytes, &flags, (OVERLAPPED *) lpIoData->oOverlapped, NULL) == SOCKET_ERROR) {            if (WSAGetLastError() != ERROR_IO_PENDING) {                return;            }        }    }}void Iocp::ServerWorkThread(VOID * _this) {    Iocp * lpTemp = (Iocp *) _this;    HANDLE hPlePort = (HANDLE) lpTemp->h_ComPlePort;    DWORD dwBytes;    LPPLEDATA lpPleData = NULL;    LPIOData lpIoData = NULL;    while (TRUE) {        GetQueuedCompletionStatus(hPlePort, &dwBytes, (PULONG_PTR *) &lpPleData, (LPOVERLAPPED *) &lpIoData, INFINITE);        if (dwBytes == 0 || lpIoData == NULL) {            printf("there is a socket away\n");            free(lpPleData);            free(lpIoData);            continue;        }        lpIoData->dRecv = dwBytes;        lpIoData->szBuffer[lpIoData->dRecv] = 0;        lpTemp->lpFun(lpPleData, lpIoData->szBuffer);        lpIoData->dRecv = 0;        ZeroMemory(lpIoData->oOverlapped, sizeof(OVERLAPPED));        lpIoData->wsBuffer.len = BUFFER_SIZE;        lpIoData->wsBuffer.buf = lpIoData->szBuffer;        if (WSARecv(lpPleData->sSocket, (WSABUF *) lpIoData->wsBuffer, 1, &recvBytes, &dwFlag, (OVERLAPPED *) lpIoData->oOverlapped, NULL) == SOCKET_ERROR) {            if (WSAGetLastError() != ERROR_IO_PENDING) {                return;            }        }    }}void Iocp::SetReadProc(VOID * lprFun) {    lpFun = (ReadProc) lprFun;}

转载地址:http://iqojz.baihongyu.com/

你可能感兴趣的文章
python在使用HTMLTestRunner时,报告为空,错误提示<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf_8'>...
查看>>
python在gpu上运行_【python】python开启GPU加速
查看>>
Python在def函数中使用for循环
查看>>
Python在def函数中使用for循环
查看>>
Python在Conda环境中,但在Windows虚拟环境中没有激活
查看>>
python系列【仅供参考】:python pip 错误 ModuleNotFoundError: No module named pip._internal 解决办法
查看>>
python图像条状状噪声,使用PYTHON PIL从验证码图像中删除背景嘈杂的线条
查看>>
Python图像处理:从内存加载jpeg
查看>>
python固定后缀(名物化词汇)词频统计:抽取+统计+可视化
查看>>
python商品评论数据采集与分析可视化系统 Flask框架 requests爬虫 NLP情感分析 毕业设计 源码
查看>>
python商品数据分析可视化系统(带爬虫)京东销售数据分析 计算机毕业设计 源码下载
查看>>
python商品库存管理系统 django框架 商品网站 MySQL数据库 源码下载 计算机毕业设计
查看>>
Python哪个版本最稳定好用2023.10.19
查看>>
Python和黑客技术的渊源
查看>>
Python和RF编写接口自动化
查看>>
Python和RF编写web自动化
查看>>
python和js哪个难_【Python】记一次学习,Python 与 js 在实现闭包时的差异
查看>>
python和java哪个更值得学——来自知乎高赞回答
查看>>
python和c混合编程 github_在pycharm中使用git版本管理以及同步github的方法
查看>>
python命名空间更改_Python模块xml.etree.ElementTree自动修改xml命名空间键
查看>>