none
在使用完成端口技术的TCP服务器中如何正确的关闭超时的连接 RRS feed

  • 问题

  • 首先服务器接受了一个连接,然后投递了一个WSARecv,假定过了一分钟该请求还没有从GetQueuedCompletionStatus调用中返回,我就判断该读请求超时了,这时我需要关闭连接。
    但是可能出现这种问题,即在我认定超时之后但真正调用closesocket之前WSARecv刚好成功返回了,然后在投递下一个IO请求之前,调用closesocket关闭了该连接并且该句柄马上被其它新来的客户重用了,则投递的下一个IO请求就会错误的投递到新来的客户上。当然可以通过使用DisconnectEx加TF_REUSE_SOCKET标志来解决,但是就会卡上30秒,不知各位有没有什么好办法
    2009年5月17日 5:16

答案

  • 抱歉没看清楚你上面那个问题.
    我说的IOCP是保证一个socket只有一个线程处理它,所以不用担心会冲突的意思是,你只投递了一个WSARecv,所以IOCP保证一个完成消息只有一个WorkerThread线程处理它。
    若你同时投递好几个重叠WSARecv操作的话到底发生什么我也不知道,不过可以做个试验看看:)
    用IOCP一般一个SOCKET只投递一个WSARecv吧?最多再同时叠加一个WSASend,这两个就算是在两个WorkerThread线程同时执行也不会冲突.不过这要看你怎么写了.


    Hello world
    2009年5月23日 7:27
    版主

全部回复

  • closesocket关闭不安全,你调用PostQueuedCompletionStatus给那个socket故意发送一个错误过去,然后通过WorkerThread里的错误处理来关闭它.
    Hello world
    2009年5月21日 14:30
    版主
  • 调用PostQueuedCompletionStatus可以构造一个完成包,但如何让具体的socket产生一个错误?
    2009年5月22日 1:26
  • 这个必须要看你的WorkerThread如何处理错误而定。
    我原来是用WSASend发送一个大小为0的包以投递一个特殊的完成消息然后关闭socket。I
    OCP是保证一个socket只有一个线程处理它,所以不用担心会冲突。
    Hello world
    2009年5月22日 4:40
    版主
  • "IOCP是保证一个socket只有一个线程处理它"是什么意思?是不是如果我们同时投递了几个IO请求到同一个socket,并且有几个工作线程都等待在GetQueuedCompletionStatus上,但是
    同一时间内只会有一个该socket的完成包从其中一个工作线程的GetQueuedCompletionStatus的等待上返回?如果是这个意思,请问你是从哪儿知道这个规则的,我在MSDN上没有查到这个,谢谢
    2009年5月23日 3:10
  • MSDN CreateIoCompletionPort Remark部分


    Hello world
    2009年5月23日 5:00
    版主
  • 不好意思,到底是那一句,本人愚笨硬是没看出来,Vonger兄能不能把那一句贴出来
    2009年5月23日 6:10
  • 抱歉没看清楚你上面那个问题.
    我说的IOCP是保证一个socket只有一个线程处理它,所以不用担心会冲突的意思是,你只投递了一个WSARecv,所以IOCP保证一个完成消息只有一个WorkerThread线程处理它。
    若你同时投递好几个重叠WSARecv操作的话到底发生什么我也不知道,不过可以做个试验看看:)
    用IOCP一般一个SOCKET只投递一个WSARecv吧?最多再同时叠加一个WSASend,这两个就算是在两个WorkerThread线程同时执行也不会冲突.不过这要看你怎么写了.


    Hello world
    2009年5月23日 7:27
    版主
  • 看来也只有使用DisconnectEx或对同一个socket的WSARecv、WSASend、closesocket的操作加锁的方法了,谢谢Vonger的热心:)
    2009年5月23日 7:37