当我传输的数据量较小时,接收方能正确将数据完全接收;但是当我传输的数据量较大时,接收方所接受的数据就不完整了,有数据丢失现象,请问各位指点,该如何实现传输大量数据时,数据的完整性?

解决方案 »

  1.   

    你用的是udp协议把
    采用tcp协议,会自动找包
      

  2.   

    to zyg0(影子(努力吃饭中)):   请你说的详细一点!
       多谢!
      

  3.   

    vb的winsock他的缓存是8K
    如果数据超过8k就会出现丢包,这样只能通过拆包来处理,不会要我贴代码吧,网上到处都是
      

  4.   

    to zyg0(影子(努力吃饭中)):   在这里,我请教的是Mscomm控件传输数据,而不是Winsock呀!
      

  5.   

    to zyg0(影子(努力吃饭中)):
       
       在大标题中的'拨号'还不够明白吗?
      

  6.   

    我用winsock也能实现拨号上网传数据
      

  7.   

    to zyg0(影子(努力吃饭中)):   那你能说的详细一些吗?具体你是怎么实现的呢?
       你没有使用Mscomm控件吗?
      

  8.   

    只要能上网就能用socket 做服务器和客户端,就可以叫服务器客户端传数据
      

  9.   

    赫赫,com编程我不会,socket编程我倒可以帮你
      

  10.   

    不过还是要谢谢你: zyg0(影子(努力吃饭中))
      

  11.   

    我想不管是com还是socket,传输机制都是一回事,因连接状态与传输线路的条件不同,对于大数据,都是分段传输的。也就是说在接收数据时,要有个缓存机制,你可用字节数组,分段发送与接收,若数据量过大,考虑内存会吃不消,一般都是用文件来缓存的。
    你可把每次收到的数据按包的大小依次写入文件,在发送方最后要给个结束标志,接收方一旦检测到结束标志就可以把整个文件做为数据处理了。
    socket我常用,几百M 数据都传输过,每次能收到的包的大小也是不定的,从几十Byte到几Kbyte都有,要看网络状态,一般局域网包要大一些。
    MsComm就没怎么用过,只知道它不会象Tcp协议那样为你分包传输,我觉得不应采用轮询方式接收大数据,应采用以事件驱动为主的应答方式,主动对数据分段,每次发送一段,接收方在OnComm事件中通过CommEvent检测接收数据,并及时采用Input属性接收数据和删除端口缓冲区,再请求发送下一段,如此往复才行。
      

  12.   


    楼上说的有理,在Mscomm的OnComm事件中我所采用的就是楼上所说的方式,但是在传输过程中,少量数据在接收时是没有问题的,一旦数据量大时就有数据丢失的现象,对此我是疑惑不解呀!还请指教!
      

  13.   

    如果是大量数据接收的时候,你必须要分块接收,因为COM传输过来的数据有时候比较慢,所以你必须分时分块接受,才可以,我以前也遇到过后来搞定了
      

  14.   

    不知你传输时用的是什么数据类型,我建议不要用String,因为VB内部所有String转换自动为Unicode编码,这在分包时会出问题,我在socket传输时常遇到一个中文被字符分在前两个包之中,而VB不会为你前连接起来的,却会把它转成了两个乱码。
    用字节数组就没问题了,另外你可尝试减小每个包,也许缓冲区不够呢。
    还一种可能是:你没等接收方应答并处理完相应的系统事件(包括清空缓冲区,必要时应插入DoEvents函数),发送方就继续发送下一个包了,这会造成接收方缓冲溢出并将数据切断的。好象通过CommEvent检测到comEventRxOver值,可发现这个问题。
      

  15.   

    是的,网络传输都是按字节发送,VB隐藏了这个概念,使用控件可以发送字符串,这对于小包没问题,因为数据都可放在一个包中一次发送。而数据量大的时候,将会面临分包,一个中文是两个字节,极有可能正好被从中间分开,各放在了前一个包尾与后一个包头之中,这时VB接收会不认识这半个字符,转成Unicode字符串时,会自动加字节chr(0),形成乱码。
    所以大数据文本传输时一定也要用字节数组(非文本当然只能用字节数组),而且转成数组前也要注意一个编码转换的问题,最佳方案是都用ANSI编码:
    发送端用
    Dim a() As Byte
    a = StrConv(Txt, vbFromUnicode)
    发送a接收端用
    Txt=(a,vbUnicode)
    转回String这时的a应该是已接收完成的全部数据,不然又会有乱码。
    当然,若是数据更大,建议存入文件,那就更简单了,接收端每次读完缓冲直接将a用Binary方式写入文件最后,就行了,不必转换。
      

  16.   

    to homezj(小吉) :
      
        楼上说的传输大量数据我明白了,但是对于如何传文件,还是有些不太明白,你能再说的详细些吗?
        谢谢!
      

  17.   

    to homezj(小吉) :
      
       从楼上的表述中,我的理解似乎是将接收的数据用Binary方式写入文件,那么对于传送方是以何种方式传送呢?
      

  18.   

    传送方也是Binary方式呀,也就是字节数组,不过我对Mscomm有些陌生,它可能无法发送字节数组,但发送字符串也行,只是接收时有点麻烦,你需检测每次最后一个字节是否是chr(0),对字符串可用最后一个字符的Asc(s) Mod 256 =0来判断,若是则需保留Asc(s)\256这个字节,等到下个包到来后,再与下个包的首字节拼成一个汉字。
    不过,我觉得每次发送内容尽量少一些(多发送几次就是了),应该没有上面的麻烦,你的问题很可在于每发送内容过大,超出缓冲区,或缓冲区来不及清空,下次数据又来了,造成的。一定要留给系统清空缓冲区的机会(可用DoEvents),不然在连续的循环中,虽然你要求清空缓冲区,但系统并没有机会执行,这种错误在网络通讯中也常见。