关于AcceptEx

本文介绍了一个基础的IOCP模型示例,重点讲解如何结合AcceptEx进行网络编程。通过将监听套接字与IOCP关联,利用GetQueuedCompletionStatus接收返回的lpCompletionKey和lpOverlapped参数。尽管AcceptEx不会直接触发GetQueuedCompletionStatus,但通过预先分配的socket和内存块,可以避免频繁的accept调用,提高效率。注意在实际应用中可能需要使用CancelIoEx来取消无关线程的操作,并检查WSASend的发送完成情况。
摘要由CSDN通过智能技术生成

最基础的IOCP例子, 没有使用扩展函数AcceptEx:   IOCP模型

* 关于iocp的核心就一点: 

GetQueuedCompletionStatus 将携带返回2个重要的参数, 一个lpCompletionKey, 一个lpOverlapped.

lpCompletionKey : 是 CreateIoCompletionPort((HANDLE)clientSocket , hIOCP,(ULONG_PTR)自定义的结构,0); 跟

iocp绑定的一个自定义参数;

lpOverlapped : 是传递给 WSASend /  WSARecv 的参数;

这2个参数最终会被GetQueuedCompletionStatus 携带回来.

 

同样的 , AcceptEx 也要传递一个Overlapped结构,现在问题来了,如果只调用了AcceptEx ,

GetQueuedCompletionStatus  是不会返回的, 因为只有跟 iocp 关联(CreateIoCompletionPort)的HANDLE / SOCKET 才会

被触发, 因此只需要把 监听套接字 跟iocp 关联即可;

   

 

下面代码使用了AccpetEx 和一个用于获取地址的扩展函数[此函数可以先忽略].

总体来说就是预先分配一些socket , 以及相关的内存块[到时有客户进来后,直接使用此内存块接受数据]; 

不再让accept系统调用来创建socket了. 

所有需要注意的点都写在注释里了.

下面代码里没有使用  CancelIo 之类的函数,如果实际需要直接用 CancelIoEx 来取消无关线程的Overlapped操作,

 

另:在发送数据[WSASend] 完成后 , 需要检查是否发送完成, 如果没有发完需要继续发送.

#include <mswsock.h>
#include <deque>
#include <vector>
#define IO_ACCEPT 1
#define IO_READ  2
#define IO_WRITE 3
#define BUFFSIZE 4096
#define SPINCOUNT 4000
struct Per_IO_Data;
std::deque<Per_IO_Data*> io_pool;
CRITICAL_SECTION io_pool_cs;

LPFN_ACCEPTEX FuncAcceptEx = NULL;
LPFN_GETACCEPTEXSOCKADDRS FuncGetAddr  = NULL;

struct Per_Sock_Data{
    SOCKET sock;
    SOCKADDR_IN addr;
    HANDLE iocp;
    Per_Sock_Data():sock(INVALID_SOCKET), iocp(INVALID_HANDLE_VALUE){}
};
struct Per_IO_Data{
    OVERLAPPED ol;
    WSABUF wsabuf;
    char *buf;
    int ioMode; //读 写 接受
    SOCKET sAcceptSock; //acceptex 预先创建的socket
    int nTotalBytes;
    int nSendBytes;
    Per_IO_Data(): buf(NULL) ,ioMode(-1) , sAcceptSock(INVALID_SOCKET)
      ,nSendBytes(0), nTotalBytes(0)
    {
        memset(&ol, 0 , sizeof(ol));
    }
    ~Per_IO_Data(){
        if(buf) delete buf;
    }
};

void resetPerIOData(Per_IO_Data * pdata , int mode = -1){
    if(!pdata) return;
    memset(&pdata->ol, 0 ,sizeof(OVERLAPPED));
    if(pdata->buf)
        memset(&pdata->buf,0,sizeof (char) * BUFFSIZE);
    pdata->wsabuf.buf=pdata->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值