我学习IOCP主要是从小猪前辈的这篇文章学的。
http://blog.csdn.net/piggyxp/article/details/6922277现在有一个问题:
小猪前辈这篇文章里面主要是教学IOCP的原理,并没有加入心跳机制。
做项目根据需要加入了心跳机制。
用的是定时器实现,但是在检测到超时,关闭socket的时候出现了问题。
具体描述:他的项目里有两个结构体一个是:
typedef struct _PER_SOCKET_CONTEXT  
{    
  SOCKET                   m_Socket;              // 每一个客户端连接的Socket  
  SOCKADDR_IN              m_ClientAddr;          // 这个客户端的地址  
  CArray<_PER_IO_CONTEXT*>  m_arrayIoContext;   // 数组,所有客户端IO操作的参数,  
                                                        // 也就是说对于每一个客户端Socket  
                                                      // 是可以在上面同时投递多个IO请求的  
} PER_SOCKET_CONTEXT, *PPER_SOCKET_CONTEXT;  每个PER_SOCKET_CONTEXT都对应一个已经连接的socket。
该结构体用作CreateIoCompletionPort和GetQueuedCompletionStatus时候的CompletionKey。第二个结构体:
typedef struct _PER_IO_CONTEXT{  
  OVERLAPPED   m_Overlapped;          // 每一个重叠I/O网络操作都要有一个                
   SOCKET       m_sockAccept;          // 这个I/O操作所使用的Socket,每个连接的都是一样的  
   WSABUF       m_wsaBuf;              // 存储数据的缓冲区,用来给重叠操作传递参数的,关于WSABUF后面还会讲  
   char         m_szBuffer[MAX_BUFFER_LEN]; // 对应WSABUF里的缓冲区  
   OPERATION_TYPE  m_OpType;               // 标志这个重叠I/O操作是做什么的,例如Accept/Recv等  
  
 } PER_IO_CONTEXT, *PPER_IO_CONTEXT;  
每个结构体对应每一个已经连接的socket上的每个操作请求(recv/send)。里面的缓冲区用于在GetQueuedCompletionStatus返回时获取数据,在我检测到有客户端掉线后,需要释放对应的PER_SOCKET_CONTEXT结构体,和里面的每个PER_IO_CONTEXT,结构体。
但现在问题来了:
我的实现是用定时器实现的,也就是在主线程中,我在是放结构体的时候,会出现访问冲突的问题。但是,加入把每个线程(CPU内核数 * 2)都加入同步线程操作的话,会降低效率。
现在我的做法是在检测到超时后,关闭对应的socket,在进入处理线程后,检测对应状态,再释放结构体。暂时没出现错误,但感觉还不是很合理。
那么我应该怎么才能够顺利实现心跳的功能?刚接触IOCP不太会描述,有什么描述不清晰的地方也请讲一下。只剩下10分了
 Any comment is welcome.

解决方案 »

  1.   

    小猪的我看过了,自我感觉写的有些复杂了
    iocp 主要用在两个方面:1网络io,2文件读写
    当用作网络io的时候,你只要让他复杂接受和发送数据即可
    其它交给业务逻辑去处理
      

  2.   

    嗯,我碰到的问题是,在客户端断开时释放资源引起的内存重复释放的问题。现在的办法是在线程内增加了严格的线程同步机制,已经没有崩溃的现象了。
    这几天对IOCP有了更好的了解了,在操作每个CompletionKey的IO请求的代码上也加入了线程同步。不过对效率肯定有影响,暂时就先这么处理了。等项目做的差不多再思考怎么优化线程同步。