服务端DataSet的一个表里的数据通过TCP每秒一次的发送到客户端来更新一个ListView,这种应用一般采用什么方法来发送数据呢?比如winbox就是几千条的链接信息每秒更新一次,它的数据是怎么通过服务器发送到客户端来维护ListView的?我暂时是服务端遍历这个表里的每条数据,一条条发送,这样可以做到添加新行和修改变更的行,但无法删除ListView里相对应的服务器数据库已删除的行,而且是发送的明码,感觉很不好
请知道的指点一下,这种应用最好的实现方法是什么,不胜感激!

解决方案 »

  1.   

    DataSet可以序列化成XML
    您是要DataSet中的一个DataTable的资料?
    还是整个DataSet?
    应该说您的DataSet有几个DataTable?
    您可以参考这一篇,将整个DataSet序列化送到客户端,然后Bind DataSet
    http://www.codeproject.com/KB/list/ListView_DataBinding.aspx
    db = new SqlConnection(ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString);db.Open();
    string SQLStatement = "EXEC [BasicSearch] @totalResults = '100',@miles =N'100'";SqlDataAdapter SQLDataAdapter = new SqlDataAdapter(SQLStatement, db);
    DataTable dtResult = new DataTable();
    SQLDataAdapter.Fill(dtResult);
    SQLDataAdapter.Dispose();
    ListView1.DataSource = dtResult;
    db.Close();
    这段代码是ListView Bind DataTable的方法
    如果您只是要送其中一个DataTable的话
    可以用序列化送到用户端后,在直接设定DataSource
      

  2.   

    DataSet  Serilize成Byte[]通过Socket   发送
    remoting
    通过XML实现数据传输
      

  3.   

    非常感谢两位的指点我需要发送的是datatable,我尝试了 DataSet Serilize成Byte[]通过Socket 发送 的方法,数据表现在可以很高效的到达客户端,但ListView没有DataSource方法啊,用DataSet中的表更新ListView的最高效的方法是什么呢?
      

  4.   

    把整个datatable序列化后发送
    private void sendData(string str)
            {
                SqlDataAdapter da = new SqlDataAdapter(str,conn);
                DataSet ds = new DataSet();
                da.Fill(ds,"mytable");
                BinaryFormatter formatter = new BinaryFormatter();
                NetworkStream stream = new NetworkStream(currentSocket);
                formatter.Serialize(stream,ds);
                stream.Flush();
                stream.Close();
            }
      

  5.   

    服务端将DataSet序列化、分包发送        public static MemoryStream GetStreamFormatData(DataSet dsOriginal)
            {
                byte[] binaryDataResult = null;
                MemoryStream memStream = new MemoryStream();
                IFormatter brFormatter = new BinaryFormatter();
                dsOriginal.RemotingFormat = SerializationFormat.Binary;            brFormatter.Serialize(memStream, dsOriginal);
                return memStream;
            }
                DataSet ds = new DataSet();
                ds.Tables.Add(DT_Temp.Copy);            MemoryStream memStream = DataFormatter.GetStreamFormatData(ds);
                ds = null;
                memStream.Seek(0, SeekOrigin.Begin);            int DataSize = memStream.Length;
                //If File.Exists("E:\1.txt") = False Then
                //    Dim WS = New FileStream("E:\1.txt", FileMode.Create)
                //    Dim BW = New BinaryWriter(WS)
                //    BW.Write(memStream.ToArray)
                //    BW.Close()
                //    WS.Close()
                //End If            //Dim ds1 As New DataSet
                //ds11 = DataFormatter.StreamRetrieveDataSet(memStream)            if (workerSocket.Connected)
                {
                    int LostSize = DataSize;
                    int NowSize = 1016;
                    try
                    {
                        string Data = string.Format("{0}", DataSize);
                        byte[] ByteData = DataFormatter.GetbyData(10001001, Data);
                        workerSocket.Send(ByteData, ByteData.Length, SocketFlags.None); //发送序列化数据总长度
                        Thread.Sleep(50);
                        while (true) //分包发送
                        {
                            if (LostSize == 0)
                                break; 
                            byte[] byData = new byte[1024];
                            int place = 0;
                            if (LostSize < 1016)
                                NowSize = LostSize;
                            Buffer.BlockCopy(BitConverter.GetBytes(10001002), 0, byData, place, 4);
                            place += 4;
                            Buffer.BlockCopy(BitConverter.GetBytes(NowSize), 0, byData, place, 4);
                            place += 4;
                            byte[] buff = new byte[NowSize];
                            memStream.Read(buff, 0, NowSize);
                            Buffer.BlockCopy(buff, 0, byData, place, buff.Length);                        workerSocket.Send(byData, byData.Length, SocketFlags.None);                        if (LostSize >= 1016)
                                LostSize -= 1016;
                        }                }
                    catch (Exception ex)
                    {
                    }            }
    客户端接收后反序列化        public static DataSet StreamRetrieveDataSet(MemoryStream memStream)
            {
                DataSet dataSetResult = null;
                IFormatter brFormatter = new BinaryFormatter();            object obj = brFormatter.Deserialize(memStream);
                dataSetResult = (DataSet)obj;
                return dataSetResult;
            }
                SocketPacket theSockId = (SocketPacket)asyn.AsyncState;            int iRx = theSockId.thisSocket.EndReceive(asyn);            MemoryStream memStream = new MemoryStream();
                memStream.Write(theSockId.dataBuffer, 0, iRx);
                memStream.Seek(0, SeekOrigin.Begin);
                byte[] CommandByte = new byte[4];
                byte[] DataLength = new byte[4];
                memStream.Read(CommandByte, 0, 4); //取包类型
                memStream.Read(DataLength, 0, 4); //取包数据长度
                int Dlen = BitConverter.ToInt32(DataLength, 0);
                byte[] byData = new byte[Dlen];
                memStream.Read(byData, 0, Dlen); //取包数据
                switch (BitConverter.ToInt32(CommandByte, 0))
                {
                    case 10001001: //DataSet序列化数据总长度
                        TempDT_Leng = Encoding.Default.GetString(byData);
                        TempDT_Stream = new MemoryStream(TempDT_Leng);
                        break;
                    case 10001002: //向内存流写DataSet序列化数据
                        TempDT_Stream.Write(byData, 0, byData.Length);
                        if (TempDT_Leng == TempDT_Stream.Length)
                        {
                            GZDataSet();
                        }
                        break;
                    default:
                        Debug.Print(Encoding.Default.GetString(byData));
                        break;
                }
            private void GZDataSet()
            {
                TempDT_Stream.Seek(0, SeekOrigin.Begin);            //If File.Exists("E:\2.txt") = False Then
                //    Dim WS = New FileStream("E:\2.txt", FileMode.Create)
                //    Dim BW = New BinaryWriter(WS)
                //    BW.Write(TempDT_Stream.ToArray)
                //    BW.Close()
                //    WS.Close()
                //End If            MyDataSet = DataFormatter.StreamRetrieveDataSet(TempDT_Stream);        }
    现在出现的问题是:在分析完成之前就遇到流结尾。可以确定客户端分包接收到的序列化数据是绝对完整的,为了确定数据是完全无误的,我除了调试看流属性,将流的值复制出来看内容之外,甚至将服务端待发送的序列化流和客户端接收到的序列化流写到文本文件,用UE二进制对比了,一个字节都不差的百度、google了几个小时,搜到的都是一个说法:差了 Stream.Seek(0, SeekOrigin.Begin);
    但我没差指针回零
    实在找不到问题所在,请达人指点
      

  6.   

    在分析完成之前就遇到流结尾这个问题是TCP粘包问题~!!!!!!!!!!!!解决放法:发送数据之后暂停线程一下(SEEP函数(100豪秒))
      

  7.   

     while (true) //分包发送
                        {
                            if (LostSize == 0)
                                break; 
                            byte[] byData = new byte[1024];
                            int place = 0;
                            if (LostSize < 1016)
                                NowSize = LostSize;
                            Buffer.BlockCopy(BitConverter.GetBytes(10001002), 0, byData, place, 4);
                            place += 4;
                            Buffer.BlockCopy(BitConverter.GetBytes(NowSize), 0, byData, place, 4);
                            place += 4;
                            byte[] buff = new byte[NowSize];
                            memStream.Read(buff, 0, NowSize);
                            Buffer.BlockCopy(buff, 0, byData, place, buff.Length);                        workerSocket.Send(byData, byData.Length, SocketFlags.None);                        if (LostSize >= 1016)
                                LostSize -= 1016;                      Thread.Sleep(50); //加上这句
                        }
      

  8.   

    把整个datatable序列化后发送
    private void sendData(string str)
      {
      SqlDataAdapter da = new SqlDataAdapter(str,conn);
      DataSet ds = new DataSet();
      da.Fill(ds,"mytable");
      BinaryFormatter formatter = new BinaryFormatter();
      NetworkStream stream = new NetworkStream(currentSocket);
      formatter.Serialize(stream,ds);
      stream.Flush();
      stream.Close();
      }