1.正常情况下,只要发送一个信息,我就解析,放入数据库
2.当出现网络堵塞的情况下,客户端会发送很多包过来,需要一条条的解析
3.能解决排队的问题

解决方案 »

  1.   

    包信息加校验,在服务器端进行存储,解析时判断是否收到完整的包,前提是包的收发,在服务器和客户端有良好的应答机制。如server收到client包时进行应答(不管是UDP还是TCP)
      

  2.   

    分包发送
    控制每次send的时间间隔。  
    有必须的话可以采用异步响应的试,等收到对方的响应之后再传下一部分。  
    TCP的连接控制协议只能在一定范围内控制流量,一旦流量过大,超过其网络负载,时间一长,缓存空间不够的时候数据丢失
    http://topic.csdn.net/u/20100810/12/832a3cfa-09af-4c03-99d9-84e872a040f7.html
      

  3.   

    这样写code的问题在哪?源码贴出using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Net.Sockets;
    using System.Threading;
    using System.Net;
    using ManageNet.Model;
    using ManageNet.BLL;namespace ManagerNet.CollectionData
    {
        class MainThread
        {
            #region 私有字段
            /// <summary>
            /// 数据缓冲区大小
            /// </summary>
            private int _maxPacket = 19;        /// <summary>
            /// 包的个数
            /// </summary>
            private int packetSize = 50;
            /// <summary>
            /// 用于接受消息的线程
            /// </summary>
            private Thread _receiveThread = null;        /// <summary>
            /// 用于接受和发送的网络流
            /// </summary>
            private NetworkStream _nws = null;
            #endregion
            /// <summary>
            /// 启动接受消息线程并显示相关信息
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            public void StartThread()
            {
                _receiveThread = new Thread(new ThreadStart(ReceiveMsg));
                _receiveThread.Start();
                //online_cb.Enabled = false;
            }
            /// <summary>
            /// 接受消息的线程执行体
            /// </summary>
            private void ReceiveMsg()
            {
                TcpListener objTcpListener = null;
                try
                {
                    IPAddress objIPAddress = IPAddress.Parse("192.168.1.35");
                    //新建侦听器
                    objTcpListener = new TcpListener(objIPAddress, 9000);
                    //启动 Listener 对象
                    objTcpListener.Start();
                }
                catch (Exception)
                {
                    if (objTcpListener != null)
                    {
                        objTcpListener.Stop();
                    }
                    return;
                }            //接受客户端请求
                
                //TcpClient objTcpClient = objTcpListener.AcceptTcpClient();
                //取得流
                //TcpClient tc = (new TCPConnection()).Connect();
                //_nws = objTcpClient.GetStream();
                while (true)
                {
                    //byte[] packet = new byte[_maxPacket * packetSize];
                    Socket soc = objTcpListener.AcceptSocket();
                    byte[] packet = new byte[_maxPacket];
                    //_nws.Read(packet, 0, packet.Length);
                    soc.Receive(packet, packet.Length, SocketFlags.None);
                    //AB 00 01 04 0C 05 00 40 25 0B 01 14 0E 32 00 00 00 AF F6
                    byte[] crc = hqjysj(packet);//获得校验数据
                    byte[] jysj = gqjysj(packet);//获得即要校验的数据
                    byte[] crc_yz = SendMess.CRC16(jysj, byte.Parse(packet.Length - 3 + ""));
                    if (this.PasswordEquals(crc, crc_yz))//验证是否校验成功
                    {
                        //通过校验
                        sjjx(packet);
                    }
                    else
                    {
                        packet = null;
                    }
                }
            }
            /// <summary>
            /// 比较两个字节数组是否相等
            /// </summary>
            /// <param name="b1">byte数组1</param>
            /// <param name="b2">byte数组2</param>
            /// <returns>是否相等</returns>
            private bool PasswordEquals(byte[] b1, byte[] b2)
            {
                if (b1.Length != b2.Length) return false;
                if (b1 == null || b2 == null) return false;
                for (int i = 0; i < b1.Length; i++)
                    if (b1[i] != b2[i])
                        return false;
                return true;
            }
            /// <summary>
            /// 获取校验数据
            /// </summary>
            /// <param name="packet"></param>
            /// <returns></returns>
            private static byte[] gqjysj(byte[] packet)
            {
                byte[] crcb = new byte[packet.Length - 3];
                for (int i = 1; i < packet.Length - 2; i++)
                {
                    crcb[i - 1] = packet[i];
                }
                return crcb;
            }
            /// <summary>
            /// 获取校验数据
            /// </summary>
            /// <param name="packet">完整包</param>
            private byte[] hqjysj(byte[] packet)
            {
                //截取需要校验的数据
                byte[] jyb = new byte[2];
                jyb[0] = packet[packet.Length - 2];
                jyb[1] = packet[packet.Length - 1];
                return jyb;
            }
            /// <summary>
            /// 数据解析
            /// </summary>
            /// <param name="packet">截取后的数据包</param>
            private static void sjjx(byte[] packet)
            {
                //解析数据
                //1.地址
                string dz = Convert.ToString(packet[1], 10) + Convert.ToString(packet[2], 10);
                //2.解析功能码
                string gnm = Convert.ToString(packet[3], 10);
                switch (gnm)
                {
                    case "4":
                        //3.数据长度
                        string sjcd = Convert.ToString(packet[4], 10);
                        //4.压力
                        double yl = SendMess.QLSWJUnPackBCD(new byte[] { packet[5], packet[6] }, 4, 3);
                        //5.电量
                        double dl = SendMess.QLSWJUnPackBCD(new byte[] { packet[7], packet[8] }, 4, 3);
                        //6.年月日时分秒
                        string year = "20" + Convert.ToString(packet[9], 10);
                        string month = Convert.ToString(packet[10], 10).Length < 2 ? "0" + Convert.ToString(packet[10], 10) : Convert.ToString(packet[10], 10);
                        string day = Convert.ToString(packet[11], 10).Length < 2 ? "0" + Convert.ToString(packet[11], 10) : Convert.ToString(packet[11], 10);
                        string hour = Convert.ToString(packet[12], 10).Length < 2 ? "0" + Convert.ToString(packet[12], 10) : Convert.ToString(packet[12], 10);
                        string min = Convert.ToString(packet[13], 10).Length < 2 ? "0" + Convert.ToString(packet[13], 10) : Convert.ToString(packet[13], 10);
                        string sec = Convert.ToString(packet[14], 10).Length < 2 ? "0" + Convert.ToString(packet[14], 10) : Convert.ToString(packet[14], 10);
                        string mea_time = year + "-" + month + "-" + day + " " + hour + ":" + min + ":" + sec;
                        //7.状态位
                        string state = Convert.ToString(packet[15], 10) + "" + Convert.ToString(packet[16], 10);
                        //入库
                        insertData(dz, yl, dl, mea_time);
                        break;
                    default:
                        break;
                }        }
            /// <summary>
            /// 插入数据库
            /// </summary>
            /// <param name="dz">地址</param>
            /// <param name="yl">压力</param>
            /// <param name="dl">电量</param>
            private static void insertData(string dz, double yl,double dl,string mea_time)
            {
                Pn_datacollection pd = new Pn_datacollection();
                pd.Mp_id = dz;
                pd.Dc_pressure = yl + "";
                pd.Dc_flowelectric = dl + "";
                pd.Dc_collectiondate = mea_time;
                Pn_datacollectionBL.Add(pd);
            }
        }
    }
      

  4.   

    每次包的最大不得超过1024,我很久以前写了个SOCKET的数据传递,要的话告诉我你的联系方式
      

  5.   

    我想要一份学习.
     邮箱:[email protected]
     谢谢。
      

  6.   

    我也想要一份,谢谢![email protected]