CAsyncSocket 在多大程度上能保证某个消息的完整性?
即:在流模式下,用 CAsyncSocket::Send(...)函数发送字节流,大小为N字节;接受端发生OnReceive事件,并触发回调函数,此时缓冲区中收到了多少字节?N?< N?
1、和 N 的大小有关系吗?
2、和网络状况有关系吗?
3、和缓冲区大小有关吗?
4、还是都有关系,?
5、普通情况下哪个因素占主导?
6、发生哪种特殊情况概率大?分别会出什么现象?常用应对方式是什么样的?
谢谢指教,因为问题较多,我送45分了

解决方案 »

  1.   

    发送n个数据,第一次onreceive()接到多少个?
    这个问题和发送n的大小/网络的情况等都有关系。
    发送n个接收n个,这是实际的最终结果。因此,你需要在发送/接收双方通过协议(数据头/数据标示/数据长度/数据/数据尾)来保证接收的完整性。也就是,onreceive()后,将数据放入缓冲区中,然后判断接到的数据的头/尾/格式等,只有接到完整的一帧数据后,才可以进行数据的处理。
    这样,你完全不必要考虑第一次onreceive()接到多少个数据。
      

  2.   

    对于流套接字上收发数据所用的函数,需要明白的是:它们不能保证对请求的数据量进行读取或写入。比如说,一个2 0 4 8字节的字符缓冲,准备用s e n d函数来发送它。
    ret = Send(s, sendBuff, nBytes, 0);
    对s e n d函数而言,可能会返回已发出的少于2 0 4 8的字节。r e t变量将设为发送的字节数,
    这是因为对每个收发数据的套接字来说,系统都为它们分配了相当充足的缓冲区空间。在发送数据时,内部缓冲区会将数据一直保留到应该将它发到线上为止。几种常见的情况都可导致这一情形的发生。比方说,大量数据的传输可以令缓冲区快速填满。同时,对T C P / I P来说,还有一个窗口大小的问题。接收端会对窗口大小进行调节,以指出它可以接收多少数据。如果有大量数据涌入接收端,接收端就会将窗口大小设为0,为待发数据做好准备。对发送端来说,这样会强令它在收到一个新的大于0的窗口大小之前,不得再发数据。在使用s e n d调用时,缓冲区可能只能容纳1 0 2 4个字节,这时,便有必要再提取剩下的1 0 2 4个字节。因为流套接字是一个不间断的数据流,应用程序在读取它时,和它应该读多少数据之间通常没有关系。如果应用需要依赖于流协议的离散数据,你就有别的事要做。如果所有消息长度都一样,则比较简单.
    while(nLeft>0)
    {
       ret = Recieve(s, &recBuff[idx], nLeft, 0);
       if(ret == SOCKET_ERROR)
       {
          //ERROR
       }
       idx += ret;
       nLeft -= ret;
    }消息长度不同,处理也可能不同。因此,有必要利用你自己的协议来通知接收端,即将到来的消息长度是多少。比方说,写入接收端的前4个字节一直是整数,表示即将到来的消息有多少字节。然后,接收端先查看前4个字节的方式,把它们转换成一个整数,然后判断构成消息的字节数是多少,通过这种方式,便开始逐次读取。