用SerialPort类做的一个串口通信的测试程序,添加了DataReceived事件处理方法,用两台机器串口直接对联发送数据,发送方在发送多于8个字节的数据时,接收方有时要分两次收,而且每次第一次收都是8个字节,这是为什么?
接收发送时都做了数据转换,发送时将string转换为byte数据发送,接收方也以byte类型接收,再转换成string类型显示,如果不转换发送中文时出错!

解决方案 »

  1.   

    检查一下Rthreshold属性和inbuffersize属性
      

  2.   

    对呀,我虽然不是做的串口通信,我做的是socket通信,跟你你样的问题,不过我是这样解决的
    len是我接收到的(可能是第一次接受到的)
    packlen是我发过来的一个包的大小
    while (len < packlen)
                            {
                                int TcpFile = cs.ClientSocket.Receive(cs.buff, 0, cs.buff.Length - len, SocketFlags.None);
                                 len += TcpFile;//便于while做出正确判断
                            }
    如果我接受的数据小与一个包的大小,我就再去Receive一次
      

  3.   

    串口通信和socket通信貌似还是有差别的
      

  4.   

    myup5201314() 正解。你不能假定,一次发送,就能一次接收。电脑串口通讯,我们唯一可以确认的就是,接收不会切断字节,也就是接收只发生在字节边界处,所以,我们通常在第一个字节指示发送包的长度。实际上,早期的单片机接收缓冲区只有4个bit,接收就会发生在4个位处,现在通常缓冲区8个位。对于PC来说,这个缓冲区还可以更大。串口通讯是不可靠的,第一个字节有可能丢失,造成接收异常,有时候单片机速度慢还会不能及时响应造成缓冲区溢出,结果后面发送的会冲掉前面发送的内容。这时候我们需要使用串口的控制线来进行同步。如果使用控制线,可以不需要长度,也不需要其他额外的校验,当然也可以进行一定的校验。在发送数据的时候,你可以让某个控制线始终处于高电平,当发送结束时,控制他为低电平。此外还需要缓冲区的高低电平控制,缓冲区满时拉高某个控制线的电平。对于PC来说,这些其实可以省略,PC对PC可以保证缓冲区不溢出。还可以保证接收的数据完整。你要做的,就是使用2根空闲的控制线来同步两者间数据发送。
      

  5.   

    检查一下Rthreshold属性和inbuffersize属性
    正解
      

  6.   

    串口的通讯可靠不可靠取决于环境和协议,就想同样是双绞线,用UDP协议和TCP协议传输数据可靠性是完全不一样的,串口的电气性能是没有问题的,毕竟是很成熟的技术了,并且广泛的运用在工业控制领域,所以不能说串口通讯是不可靠的。串口参数中的停止位和校验位都可以简单的纠正通讯中的错误。但楼主的问题显然不是串口不稳定造成的,若是不稳定应该产生误码才对,而不是数据流的截断!
    问题的原因应该是串口配置的问题。
      

  7.   

    那个Serlai类可以设置接收到几个字节后触发那个DataReceived的事件,你可以设置接收1个字节就触发,然后可以一次性把缓冲区里面的数据全部拿出来
    你最好设计一个好一点的协议,我曾经做的那个要有非常大的电流,有100安培还不止,搞得干扰很严重
      

  8.   

    raulredondo大哥,您能不能说说怎么设置接收到几个字节后触发那个DataReceived的事件?
      

  9.   

    suliang1984,我没有在SerialPort类中找到Rthreshold属性呀!
    接收缓冲区肯定是足够大的!
      

  10.   

    ReceivedBytesThreshold决定接收几个字节触发DataReceived,默认为1
    串口编程基本都会遇到这个问题!我的办法:定义一个全局变量,DataReceived事件连接读到的字符串,满足条件处理完当前数据后,清空变量!
      

  11.   

    串口是慢速通讯机制,当你的串口有数据到达,响应事件的时候,其实数据还没有发送完毕,如果你非要一次就接收完毕,你要设立一个延时我建议你不要设立延时,而是在你的串口指令编码中设置好标志位,例如字节的起始标志和终止标志,以及字节长度等信息,通过判断这些信息达到完成接受的目的。我做串口是采用一个死循环,一直采集,然后分割数据,把数据成块加入到ArrayList可以看我得Bloghttp://blog.csdn.net/cnming/archive/2007/05/06/1597930.aspx串口程序不处理好,会有数据掉包的现象
      

  12.   

    串口(RS232)的通讯是不可靠的,他的电气特性不同于使用对绞线的网线。1、他使用TTL电平,电压高。
    2、允许的漏电流较高,容易受到干扰,也不可以长距离传送。
    3、使用原始的高低电平来区别1、0,延时,码率不同都会造成干扰。短距离,优良环境中才能可靠工作,如果在恶劣环境中,要么使用RS485,或者使用光电串口,并且加上软件纠错。LZ的问题并非干扰,我只是告诉他,将来要注意干扰问题,在设计通讯协议的时候要充分考虑串口的不可靠。
      

  13.   

    BlueTrees(蜗牛) 正解,但只要设计合理这些问题可以避免的。cnming(cnming) 的方法也可以,曾经我用过这种发法:不适用串口类的DataReceived事件触发,而是循环判断inputbuffer中的数据长度,比如你一直要发送的数据长度是12字节,那么当判断到inputbuffer的长度大于等于12字节时读取缓冲中的数据。虽然有可能inputbuffer的数据会超出长度,将超出长度的数据截断就可以了。不过要考虑再循环中加入超时,否则有可能陷入死循环。建议自己写一个简单的传输协议,用串口做数据流的不间断传输可靠性实在不敢保证。
      

  14.   

    DataReceived事件由Rthreshold属性触发,如果Rthreshold属性设为8,发送方在发送多于8个字节但是少于16个字节的数据时,接受一次,如果发送等于或多于16个字节少于24字节,就接受两次,如此类推