刚用IOCP两天
看到一些IOCP例子
其中使用到单IO数据结构体
typedef struct _PER_IO_DATA         //单IO数据
{
OVERLAPPED ol;                //重叠结构
CHAR buf[BUFFER_SIZE];        //数据缓冲区
INT OperatorType;             //操作类型
}PER_IO_DATA,*PPER_IO_DATA;  这里面 OperatorType会分:accept,recv,send,end在IOCP工作线程里会依据OperatorType的不同去分别处理
recv,send,end这三个操作类型我都明白
但是accept会在什么时候使用?第二个问题:

解决方案 »

  1.   

    非堵塞accept才有必要考虑这个问题。
    不过也不是用IOCP来实现accept的异步处理。
    所以一般不会考虑,这只会让上层模型趋于复杂
      

  2.   

    何时对OperatorType赋值,我想在recv,或者send投递之前进行设置,只是感觉好像不太合情理。比如:
    客户端发送请求,服务器接收,OperatorType设置recv
    接收完全后,业务线程处理后,要执行send.此时OperatorType设置为send
    要是在这个时候客户端再发送命令,还能处理吗?
      

  3.   

    投递IO请求的时候,可以把单IO数据 作为参数传递的啊,这时你可以设置OperatorType
    当IO操作完成时调用GetIoCompletionStatus(),可以获得单IO数据(Overlapped结构,后面是尾随数据)
      

  4.   

    DWORD WINAPI CompletionThread(LPVOID lpParam)
    {
    CServer *pServer = (CServer*) lpParam;
           //传输字节数
    DWORD dwTrans;
    PPER_HANDLE_DATA pPerHandle;
    PPER_IO_DATA pPerIO;
    while(TRUE)
    {
    BOOL bRect = ::GetQueuedCompletionStatus(pServer->m_hCompletionPort,
    &dwTrans,(LPDWORD)&pPerHandle,(LPOVERLAPPED*)&pPerIO,WSA_INFINITE);
    if(!bRect)
    {//在此套接字有错误发生
    ::closesocket(pPerHandle->socket);
    ::GlobalFree(pPerHandle);
    ::GlobalFree(pPerIO);
    continue;
    }
    if ( 0 == dwTrans && 
    (pPerIO->OperatorType == IO_RECV ||pPerIO->OperatorType == IO_SEND))
    {//套接字被对方关闭
    ::closesocket(pPerHandle->socket);
    ::GlobalFree(pPerHandle);
    ::GlobalFree(pPerIO);
    continue;
    }
    switch(pPerIO->OperatorType)
    {
    case IO_RECV: //完成一个接收请求
    {
    pPerIO->buf[dwTrans]='\0';
    //继续接收
    WSABUF buf;
    buf.buf = pPerIO->buf;
    buf.len = BUFFER_SIZE;
    pPerIO->OperatorType = IO_RECV;
    DWORD dwFlags = 0;
    ::WSARecv(pPerHandle->socket,&buf,1,&dwTrans,&dwFlags,&pPerIO->ol,NULL);
    }
    break;
    case IO_SEND: //完成一个发送请求
                            {
                                  //同样在这里
                                  pPerIO->OperatorType = IO_SEND;
                                  ::WSASend(......)
                             }
    ;
    break;
    default :
    ;
    }
    }
    return 1;
    }
    ////////////////////////////////////////////////////
    贴代码问下。
    pPerIO->OperatorType等于IO_RECV
    继续操作WSARecv,设置pPerIO->OperatorType=IO_RECVpPerIO->OperatorType等于IO_SEND
    继续操作WSASEND,设置pPerIO->OperatorType=IO_SEND这样会不会有问题啊?
    如果我在发送数据pPerIO->OperatorType等于IO_SEND
    那客户端发送消息过来,我是不是接收不到了?
    还是我理解错误!!
    请大家给讲解讲解
      

  5.   

    没问题啊,上一次的重叠操作完成,至于下一次你想发送还是想接收,随意啊
    如果你投递了一个pPerIO->OperatorType=IO_SEND;
    那么这个也是需要排队的,得先看有没有空闲线程(LIFO)
    所以和客户端这时候是不是发送没有关系的。 
      

  6.   


    对IOCP的流程还没有完全理解!!!呵呵!!