用监听的方法接收数据,如果对方发送的字符比较长,接收的字符就会有丢失,短点的还正常
先附上我的代码
public partial class Form1 : Form
    {
        public delegate void HandleInterfaceUpdateDelegate(string text);
        private HandleInterfaceUpdateDelegate interfaceUpdateHandle;
        SerialPort sp = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);        public Form1()
        {
            InitializeComponent();
        }        private void BtnSend_Click(object sender, EventArgs e)
        {
            sp.Write(this.textBox1.Text);
        }        private void Form1_Load(object sender, EventArgs e)
        {
            if (!sp.IsOpen)
            {
                sp.Close();
                sp.Open();
            }
        }        private void UpdateLabel(string text)
        {
            this.LabReceive.Text = text;
        }        private void BtnAny_Click(object sender, EventArgs e)
        {
            interfaceUpdateHandle = new HandleInterfaceUpdateDelegate(UpdateLabel);
            sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);
            sp.ReceivedBytesThreshold = 1;
        }        void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] readBuffer = new byte[sp.ReadBufferSize];            sp.Read(readBuffer, 0, readBuffer.Length);
            this.Invoke(interfaceUpdateHandle, new string[] { Encoding.UTF8.GetString(readBuffer) });
        }        private void BtnReceive_Click(object sender, EventArgs e)
        {
            this.LabReceive.Text = sp.ReadExisting();
        }
比如对方发送uuuuxxxxxkkkkk,我这边接收的就成了kkk。

解决方案 »

  1.   

    你可以试着连着接收,看下是数据丢失了;还是数据发生了分段,你都没有处理到呢;
    在sp_DataReceived里设置断点;另外,接收的可以改为:sp.Read(readBuffer, 0, sp.ReadBufferSize);
    我以前碰到情况,byte[] readBuffer = new byte[sp.ReadBufferSize];            sp.Read(readBuffer, 0, readBuffer.Length);
    这两步之间sp.ReadBufferSize得值会有变化,
      

  2.   

    我以前这样用,没有数据丢失哦                int nByteNum = serialPort1.BytesToRead;
                    byte[] arraybyte = new byte[nByteNum];
                    serialPort1.Read(arraybyte, 0, nByteNum);
      

  3.   

    void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                thread.sleep(500);
                byte[] readBuffer = new byte[sp.ReadBufferSize];            sp.Read(readBuffer, 0, readBuffer.Length);
                this.Invoke(interfaceUpdateHandle, new string[] { Encoding.UTF8.GetString(readBuffer) });
            }
      

  4.   

    thread.sleep(500); 
    这样不好吧,要是经常性的接收,程序岂不总卡在那。
      

  5.   

    我检查过了,数据是分成两段接收的
    如果把这句this.LabReceive.Text = text 改成this.LabReceive.Text = this.LabReceive.Text + text 就不会出现那个问题。 但清空LabReceive就成了问题,如果将this.LabReceive.Text =""写到sp_DataReceived方法里,会报:“从不是创建控件LabReceive的线程访问它。” ,sp_DataReceived是调用了另一个线程,加了事件委托又成了起初那样的问题。
      

  6.   


    void sp_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    的工作原理你要明白,接收事件的触发条件并不一定是个确切的条件。 有时接收几个字节就激活,有时接收n个字节激活。 这时候,接收缓冲区并没有填充多少数据, 很可能出现字节接收不完全的情况。 300或者500毫秒基本都可以满足接收缓冲区的填充需要。 对于300-500 毫秒的等待,sleep 尚可接受。 串口通信不可靠,不抗干扰的特点决定了它绝对不可能像 udp,tcp 那样处理得十分平滑流畅。但也不至于像你说的卡在那。
      

  7.   

    public void RefreshForReceive(byte[] bytes)
    {
    if (txtMain.InvokeRequired)
    {
    ReceivData dl = new ReceivData(RefreshForReceive);
    object arg = bytes;
    txtMain.Invoke(dl, arg);
    }
    else
    {

    foreach (byte b in bytes)
    {
    txtMain.Text += String.Format("{0:X2} ",b);
    }
    txtMain.Text += "\r\n";
    }
    } void _com_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
    int bytesRead = 0;
    _com.ReceivedBytesThreshold = 100000; //关掉串口接收事件
    while (true)
    {
    if (bytesRead > 65535)
    bytesRead = 0; try
    {
    receiveBuffer[bytesRead] = (byte)_com.ReadByte();
    ++bytesRead;
    }
    catch (TimeoutException)
    {
    break;
    }
    catch
    {
    _com.ReceivedBytesThreshold = 1;
    return;
    }
    }
    if (bytesRead > 0)
    {
    byte[] bytes = new byte[bytesRead];
    Array.Copy(receiveBuffer, 0, bytes, 0, bytesRead);
    Array.Clear(receiveBuffer, 0, bytesRead);
    RefreshForReceive(bytes);
    }
    bytesRead = 0;
    _com.ReceivedBytesThreshold = 1;
    }
    这是我自己写串口调试工具的时候写的两个方法 !!你可以参考一下 !!ReceivData 是一个委托!!!!
      

  8.   

    把缓冲区接收字节大小赋值给变量 
    thread.sleep(500); 
     变量与缓冲区接收字节大小比较,缓冲区大,跳到上面,相等然后读数据区数据,出了数据