在做一个需要与下位机网络通信的项目,用TCP通信方式,一帧一帧的传输数据,即,上位机发送一帧,如果正确,下位机回复一帧,上位机收到之后判断正确性,如果正确就写入数据库,否则重新发送请求。但是因为实时性要求比较强,发送数据之后要求不要有延时,但是如果没有延时的话,接收数据的线程还没有接收到数据,上位机就已经开始判断并重发。以前没有做过网络编程,不知道该如何处理。请大家帮忙看一下,谢谢!下面是发送线程的代码
        /// <summary>
        /// 发送搜索指令线程
        /// </summary>
        private void OrderProccess()
        {
            try
            {
              
                while (m_flag)
                {
                    m_rStr = null;
                    //构造字节数组
                    Byte[] sendByte;
                    for (int k = 0; k < m_clist.Count; k++)
                    {                        //是否这个服务器内的设备IP号
                        if (m_clist[k].m_name.Contains(m_name))
                        //起始位和IP号
                        {
                            // string datastr;
                            if (!m_dataflag)
                            {
                                sendByte = m_clist[k].orderbyte;
                                //datastr = "AA" + m_clist[k].ip.ToString("X2");
                            }
                            else
                            {
                                //是否是已经搜索到的设备
                                if (m_clist[k].isFound)
                                {
                                    sendByte = m_clist[k].databyte;
                                    //datastr = "A3" + m_clist[k].ip.ToString("X2");
                                }
                                else return;
                            }                            //向每个设备最多发三次命令
                            for (int i = 0; i <= 3; i++)
                            {
                                if (!m_dataflag)
                                {
                                    //如果接收到的数据包与发送的不一致,重新发送
                                    if (!(Compare(m_rStr, m_clist[k].osendStr)) || m_rStr == null)
                                    {
                                        if (i < 3)
                                        {
                                            m_socket.Send(sendByte, sendByte.Length, 0);//发送数据
                                            ts1 = new TimeSpan(DateTime.Now.Ticks);
                                            //receiveTd = new Thread(new ThreadStart(ReceieveProccess));
                                            //receiveTd.Start(); //启动线程用于接收数据
                                            //每次发送之后延时100毫秒
                                           // Thread.Sleep(1000);
                                        }
                                        else
                                        {
                                            //如果三次都没有返回从IP列表中删除
                                            // m_clist.Remove(m_clist[k]);
                                            m_clist[k].isFound = false;
                                            break;
                                        }
                                    }
                                    //接收到相同的数据包,设备搜索成功
                                    else
                                    {
                                        //搜索到的设备个数加1
                                        ipcount++;
                                        m_clist[k].isFound = true;
                                        m_clist[k].m_name = m_name + "_" + m_clist[k].ip.ToString();
                                        //更新设备表
                                        UpDateDevice(m_da, m_clist[k].ip.ToString("X2"));
                                        break;                                    }
                                }
                                else
                                {
                                    if (m_rStr != null && m_rStr.Contains(m_clist[k].dsendStr.Substring(0, 4)))
                                    { //校验码校验数据是否正确                                        if (CRCKey_RTU(m_rStr) == 0)
                                        {
                                            //位移数据
                                            if (m_type == 1)
                                            {
                                                //与之前的记录相比较,是否有变化,如果相同,不写入数据库
                                                if (!Compare(m_rStr, m_clist[k].recordStr))
                                                {
                                                    //接收到的数据写入数据库
                                                    WriteDB(m_da, m_rStr);
                                                    m_clist[k].recordStr = m_rStr;
                                                }
                                                else break;
                                            }
                                            else
                                            {
                                                //压力数据写入数据库
                                            }
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (i < 3)
                                        {
                                            m_socket.Send(sendByte, sendByte.Length, 0);//发送数据
                                           // Thread.Sleep(100);
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if (!m_dataflag)
                    { //提示实际找到的设备
                        MessageBox.Show(m_ip.ToString() + "下搜索到" + ipcount + "个设备!");
                        //计数器清零
                        ipcount = 0;
                        Thread.Sleep(Timeout.Infinite);
                    }
                    //else 
                    //线程挂起
                    // Thread.Sleep(Timeout.Infinite);
                    //break;                }
                            }
            catch (Exception ex)
            {                //MessageBox.Show(ex.ToString());
                // MessageBox.Show("连接已断开!");            }
            finally 
            {
               
            }
        }接收:        /// <summary>
        /// 接收数据
        /// </summary>
        private void ReceieveProccess()
        {
            if (m_socket.Connected)
            {
                while (m_flag)
                {
                    byte[] receiveByte = new byte[8];//表示通过套接字一次接收的数据长度
                    try
                    {
                      
                        //接收长度为recvBytes.Length接收并将数据放进recvBytes中。参数0表示指定的传输控制方式,0就表示没有特殊行为。
                        m_socket.Receive(receiveByte, receiveByte.Length, 0);
                        //转换成16进制字符串
                        string strInfo = byteToHexStr(receiveByte);
                        //判断是否正常数据
                        if (strInfo.StartsWith("A"))
                        //收到的是回发的命令包
                        {
                            ts2 = new TimeSpan(DateTime.Now.Ticks);
                            TimeSpan ts = ts2.Subtract(ts1).Duration();
                            string spanTotalSeconds = ts.TotalSeconds.ToString(); //执行时间的总秒数                            Console.WriteLine(spanTotalSeconds);
                            if (strInfo.Substring(0, 2) == "AA")
                            {
                                m_rStr = strInfo.Substring(0, 8);                            }
                            else //收到的是数据包
                            {
                                m_rStr = strInfo.Substring(0, 16);
                            }
                        }
                                          }
                    catch (Exception ex)
                    {
                        //只有在非人为断开时才提示
                        if (!isclosing)
                        {
                            MessageBox.Show("已经与设备" + m_ip.ToString() + "断开连接" + ex.ToString());
                            //MessageBox.Show("已经与设备" + m_ip.ToString() + "断开连接");
                        }
                        m_success = false;                        break;
                    }
                    finally 
                    {
                      
                    }
                }            }
        }

解决方案 »

  1.   

    如果不等到回应,你就不断重发,这个和实时性没有任何关系啊,既然有应答,就要遵守协议,等到呼应后再做操作,如果在一定时间内没有收到应答,这时候在去重发命令,你现有的逻辑是正常的,而且这个速度应该在毫秒级总是重发,又收不到回应,你的实时性有何意义呢,而且频繁发送,还会增加网络负担,网络传输的效率除了代码上控制以外,硬件设施也是必不可少的,比如你的宽带速率,在大并发下,尤为重要
      

  2.   


    恩,硬件方面现在已经确定了,但是做下位机的同事说如果我这边延时的话他那里会有问题。我在网上看了很多有关中断线程方面的资料还是很糊涂,他的意思是我不延时,每次都等到数据到了再中断发送数据的线程来完成整个过程。
      

  3.   

    你连接上了么?你这代码看不出来你怎么连接的。搜索设备是什么意思哦?
      

  4.   

    连接的代码不在这,我这只是收发数据的代码。
      

  5.   

    你想看什么问题的答案,一样的吗?