俺本来是想问一次收一个还是多个字节好,但写着写着就觉得不能一次收多个字节。如下:  一次收一个字节会导致频繁地调用阻塞式函数GetIOCompletionPortStatus();觉得这会影响性能。  N个字节的话,如果包长度不是N的整数倍,那么收包时最后一个N字节就会填不满,就会等到下一个包的包头几个字节的到来,以填充最后一个N字节的剩余空间,收到后GetIOCompletionPortStatus()再返回。  更糟糕的情况:当处于应答方式时,服务器等待客户端的下一包数据以填充最后一个N字节空间,客户端等待回应帧,这样两边都在等,最后超时……  那这么说,只能一次收一个字节?

解决方案 »

  1.   

    TO:unsigned(僵哥(为什么我会到这里来……))
    你是说,GetQueuedCompletionStatus()的行为如同recv()?
      

  2.   

    你是说,GetQueuedCompletionStatus()的行为如同recv()?
    =======================================================
    GetQueuedCompletionStatus并不等同于recv,此只是由于用户线程提交了WSARecv之后,Winsock2内部再有服务线程做recv操作,当一次recv操作完成之后,然后发出消息通知用户线程,这个通知再由IOCP所截获,而后再通知线程队列当中新进来和线程从而使得GetQueuedCompletionStatus返回,出现错误也会返回.recv并不会充满缓冲区才返回,但是缓冲区满了之后,肯定会返回.
      

  3.   

    要注意的是,一旦返回之后,如果不调用WSARecv/recv等接收的话,系统不会再自动帮你发起recv.所以在网络特别紧张的时候,很可能你设置的缓冲区有8kb,并且对方发送过来的数据,甚至远远超过8kb,而你却有可能某次只收到一个字节的数据(当然这只是假设,基本上会是一个完整的TCP数据片).
      

  4.   

    http://www.yuanma.org/data/2006/0626/article_972.htm