服务器和客户端都使用CAsyncSocket的继承类;客户端只管发数据,send一次是一个数据包,每次这个包的大小是不一样的,包的大小和它的类型是相关的,一种类型的数据对应一种大小的数据包;比如说有“事件数据包”,其对应的一个数据包为500字节;而“文件数据包”对应的则可能为600字节;客户端发送以后,在服务器端的Onreceive事件中接收数据,但接收的时候,由于每个数据包我要保证他的完整型,即我希望能每次接收一个完整的且只接收一个数据包,语句Receive( 
void* lpBuf, int nBufLen, int nFlags = 0 );中的nBuflen就不好指定;
我做过测试,如果把nBuflen设为足够大(表示比所有类型的数据包的长度都大),则客户端发送三个数据包,服务器端只触发一次onreceive事件,也就是将三个数据包接收到了一个包里面;如果只是这样的话到还可以处理,我只要在解析包的时候再把数据分开来处理就可以了,
但是我想如果我客户端连续发了100个包,总的长度比如说  为100*500=50000字节,服务器端在onreceive中调用语句Receive,肯定要指定一个长度nBuflen,如果这个长度不一定是我的数据包的整数倍,(因为我得数据包好几种长度),那其中肯定有一个数据包被中间截断了,这样的话数据就没办法处理了
如果这种情况,该如何处理?还是用其他的通信方式,高手们给点指导,100分送上,我已经困扰好几天了,谢谢大家

解决方案 »

  1.   

    其一:“我做过测试,如果把nBuflen设为足够大(表示比所有类型的数据包的长度都大),则客户端发送三个数据包,服务器端只触发一次onreceive事件”——我怀疑你的这个结论!!
    只要系统的接收缓冲里还有数据没被你Receive,那它就会再一次触发OnReceive
    其二:“如果这个长度不一定是我的数据包的整数倍,(因为我得数据包好几种长度),那其中肯定有一个数据包被中间截断了,这样的话数据就没办法处理了”——当然有办法,而且很简单
    没有谁规定OnReceive里只能Receive一次。你可以在一次之后确认所接收的长度,如果不够,再Receive必要的长度。
      

  2.   

    事实上,在我的OnReceive里,最通常是在一个while里Recieve。我没见有什么问题哦!
      

  3.   

    呵呵,你做的测试是没问题的,因为在socket发送的时候,系统为了提高效率,会将多次发送的数据组合成一个数据包发送出去,或者把一个大包拆成几个小包发送出去,这些都是为了提供系统socket缓冲区的效率,你的测试并不能说明什么。
    解决你的问题有2种办法:
    1、如果你的协议是确定性质的:比如一个“事件数据包”后一定跟着一个“文件数据包”,那么你可以固定下接收的字节数
    2、如果你的协议支持数据包的性质是随意的,那么我建议你修改协议,比如每次发送数据包的时候先发送一个包头,表示后面数据的包性质。(比如文件包就是(char)1,事件包就是(char)2)
      

  4.   

    建议你使用FTP. FTP有两个信道, 一个完成命令的传送, 一个完成文件的传送
      

  5.   

    十分感谢楼上各位的讨论,大家说得都很有道理
    我找到一个老帖子,对这个问题也有比较好的分析,在这里共享一下,供大家一起参考讨论
    同时结帐,谢谢各位!!!
    http://community.csdn.net/Expert/topic/3168/3168017.xml?temp=.1385004