我学习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.
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.
iocp 主要用在两个方面:1网络io,2文件读写
当用作网络io的时候,你只要让他复杂接受和发送数据即可
其它交给业务逻辑去处理
这几天对IOCP有了更好的了解了,在操作每个CompletionKey的IO请求的代码上也加入了线程同步。不过对效率肯定有影响,暂时就先这么处理了。等项目做的差不多再思考怎么优化线程同步。