先贴出我线程的部分代码:
while (WAIT_OBJECT_0 != WaitForSingleObject(piocp->m_hShutDown, 0))
{
//从完成队列中读取消息
LVB_IOCPStatus = GetQueuedCompletionStatus(piocp->m_hIOCP, &LVI_TransByte,
(PULONG_PTR)&pSocketContext, &poverlapped, INFINITE);
//当完成端口出错时,返回值为0
if (!LVB_IOCPStatus)
{
//错误分两种,1、Overlapped为空;2、Overlapped不为空,详见MSDN
int iError = WSAGetLastError();
if (poverlapped)
{
if (!piocp->mFB_HandleError(pSocketContext, iError))
break;//完成端口出错,则退出该线程
}
continue;
}
else
{
//处理客户端请求
}
}
问题:假如现在A线程在给client发送文件,但还没发送完成,此时client断开了连接,则按成端口会收到两个通知(这句话对么?),一个通知是客户端断开连接,假设是由线程B接收该通知,用wsagetlasterror()返回64,另一个通知是线程A反馈的发送文件错误。问题来了,假如B先收到通知,则他会删除该连接,之后A收到了发送文件错误的通知,此时该连接已经删除了,那么该如何处理?完成端口多线程同步
while (WAIT_OBJECT_0 != WaitForSingleObject(piocp->m_hShutDown, 0))
{
//从完成队列中读取消息
LVB_IOCPStatus = GetQueuedCompletionStatus(piocp->m_hIOCP, &LVI_TransByte,
(PULONG_PTR)&pSocketContext, &poverlapped, INFINITE);
//当完成端口出错时,返回值为0
if (!LVB_IOCPStatus)
{
//错误分两种,1、Overlapped为空;2、Overlapped不为空,详见MSDN
int iError = WSAGetLastError();
if (poverlapped)
{
if (!piocp->mFB_HandleError(pSocketContext, iError))
break;//完成端口出错,则退出该线程
}
continue;
}
else
{
//处理客户端请求
}
}
问题:假如现在A线程在给client发送文件,但还没发送完成,此时client断开了连接,则按成端口会收到两个通知(这句话对么?),一个通知是客户端断开连接,假设是由线程B接收该通知,用wsagetlasterror()返回64,另一个通知是线程A反馈的发送文件错误。问题来了,假如B先收到通知,则他会删除该连接,之后A收到了发送文件错误的通知,此时该连接已经删除了,那么该如何处理?完成端口多线程同步
给你一些思路,供你参考。第一种思路:
1、固定最大连接数(如1000),事先建立好套接字数组。(也可以是结构体数组)
2、在lpCompletionKey中存放SOCKET值或者数组索引。
3、当紧急关闭时,第一个投递当然做关闭socket和释放资源,第二个以后的投递,可以根据 socket==INVALID_SOCKET 来判断和进行错误处理。
4、当然,上面的操作涉及资源竞争,加锁是必须的。第二种思路:
1、不固定最大连接数,连接后 new 一个 PER_HANDLE_CONTEXT,但这个结构体内部应具有对所有该Socket上的IO操作的记录,可以用计数器或链表。“完成端口是FIFO,有进必然有出。”当所有的进出操作都记录在案后,那么何时该关闭套接字和释放资源,你就知道了。
2、上面的操作同样需要用锁,而且用量较大,但程序是稳定的。
3、另外,提醒你虽然完成端口是FIFO,但是线程池调度是LIFO。这一点你一定要清楚,别因为通告顺序干扰了你的思路。
以上仅是思路,要想做好完成端口,这些肯定是不够的。我也只能帮到这里了。
谢谢你的回复,我所反馈的问题正如你所说的那样。那这样的话,就只能是最后一次接到完成通知时,才释放资源,之前的操作才不会非法。 我发送文件是在线程函数里调用了transmitfile来发送,我只启动一个线程时,文件发送是没问题的,但是启
动多个线程来接收完成端口通知,则会出现发送失败的现象。
我的操作流程是这样的
1、client发送下载请求
2、server收到请求后,唤醒线程A,然后A调用transmitfile发送文件
3、client通过多次recv和writefile接收文件
4、当发送完成,server端完成端口接到完成通知,释放资源