完成端口 GetQueuedCompletionStatus 异常处理

公司的校园平安卡产品,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再出错时程序可以继续保持与其他客户端的通信了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值