|
发表于 2010-12-29 11:50:32
|
显示全部楼层
本帖最后由 modern 于 2010-12-29 11:52 编辑
就这个问题,昨天下午和freeeyes各自精读msdn的相关章节。最后比较一致的观点是:
由于IOCP并没有就GetQueuedCompletionStatus的短写短读问题提供进一步说明。
但是可以肯定的是IOCP的GetQueuedCompletionStatus函数实际内部会调用重叠IO的函数。
而MSDN对于WSAGetOverlappedResult的说明比较明确。
GetQueuedCompletionStatus只有成功完成(completed successfully)才会返回读到的数据长度。
而对于其他各种情况比如重叠IO未完成(主要就是这句话),
或者完成出错,未确定状态,参数问题等,lpcbTransfer均将不会被更新,
对此我的理解是重叠IO一定会返回一个完成态或者失败,
而不会将中间的半完成态返回,因此无须处理短写短读问题。
最后的结论是对于短读的问题,代码保留如果触发做日志特殊标记。
而对于短写的问题,由于确实在逻辑上会出现乱序的问题,这解释不通。
万恶的GetQueuedCompletionStatus在完成之后会将overlaped数据结构
从IOCP的队列中dequeue出去,如果完成队列里仍然有该连接的待发数据包,
则必乱序,这时即使重新投递异步的write(WSASEND)也解决不了这个逻辑问题。
因此只能打印日志,暂不作进一步处理。
对此欢迎大家讨论,拍砖。
下面是原文:
If WSAGetOverlappedResult succeeds, the return value is TRUE. This means that the overlapped operation has completed successfully and that the value pointed to by lpcbTransfer has been updated. If WSAGetOverlappedResult returns FALSE, this means that either the overlapped operation has not completed, the overlapped operation completed but with errors, or the overlapped operation's completion status could not be determined due to errors in one or more parameters to WSAGetOverlappedResult. On failure, the value pointed to by lpcbTransfer will not be updated. Use WSAGetLastError to determine the cause of the failure (either of WSAGetOverlappedResult or of the associated overlapped operation). |
|