您的位置:首页 > 产品设计 > UI/UE

完成端口 GetQueuedCompletionStatus 异常处理

2015-11-25 14:50 453 查看
公司的校园平安卡产品,C/S结构,客户端数目大概50个,服务端采用IOCP(完成端口)与客户端通信,Socket UDP协议。

服务端程序基本流程:

 1.程序建立IOCP模型并绑定Socket,用WSARecvFrom 向IOCP通道中投递数据接收请求

 2.Work线程,整体是循环:使用GetQueuedCompletionStatus获取通道中已经完成的请求和数据,然后有一个判断:

     如果取到的是接收结果,则将收到的数据保存到接收队列,然后使用WSARecvFrom 继续投递数据接收请求

     如果取到的不是接收结果,则不做处理

 3.Work线程接收到的数据,经过加工,生成需要发送的数据,存进发送队列    

 4.Send线程,也是循环:从发送队列取数据,用WSASendTo投递发送请求

   GetQueuedCompletionStatus有时会返回error 1234,含义是“没有任何服务正在远程系统上的目标网络终结点上操作”,原因可能是某个客户端与服务端连接异常。原先服务端遇到GetQueuedCompletionStatus出错时是直接return,退出线程,然后关闭整个程序。另外有一个进程监控程序(负责监控服务器上各应用程序状态,发现应用程序退出后便将其重新启动)随后将平安卡服务端程序重新启动。GetQueuedCompletionStatus错误是偶尔出现,基本不影响正常运行。
     但是遇到某个客户端设备调试或者网络调整,GetQueuedCompletionStatus就会不断出错,导致服务端程序频繁重启,无法正常运行。因此要调整Work线程的逻辑,在GetQueuedCompletionStatus出错后记录错误信息但不要退出程序,继续保持与其他客户端的通信

    最开始考虑的很简单,是在GetQueuedCompletionStatus返回error后记下log,然后直接countinue到下一次循环。这样修改后实际运行时发现,GetQueuedCompletionStatus 返回error后程序虽然没有退出,但是却停止了与各个客户端的通信。

    分析原因:Work线程GetQueuedCompletionStatus出错后直接countinue跳到下一次循环,没有投递数据接收请求,则GetQueuedCompletionStatus取不到数据接收结果,陷入阻塞,于是数据收发也都停下了。

   重新调整,在GetQueuedCompletionStatus出错后用WSARecvFrom 投递接收请求,再执行countinue,运行验证,GetQueuedCompletionStatus再出错时程序可以继续保持与其他客户端的通信了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: