rt
问题是有时候报错,有时候正常。一半一半。数据发送和接收 没有问题的(所以代码没贴出来),数据长度和数据内容 完全一致。问题就在序列化和反序列化本身。
报错的类型是
有时候 : “二进制流“0”不包含有效的 BinaryHeader。这可能是由于无效流,或由于在序列化和反序列化之间的对象版本更改。”
有时候:“无法将位于索引42(这个索引不定)处的字节[FF](这个FF 每次都是)由指定的代码页转换为Unicode”。当我跟踪索引位置的内容时 发现,有时是 255(即FF,报错提示是对的),有的时候不是255(不是FF)。也就是说 这个提示不准确。Server端 序列化代码     public byte[] getObjectBytes(object o)
        {
            try
            {
                #region//old Code
                BinaryFormatter bf = new BinaryFormatter();
                bf.TypeFormat = System.Runtime.Serialization.Formatters.FormatterTypeStyle.TypesWhenNeeded;
                MemoryStream ms = new MemoryStream();
                bf.Serialize(ms, o);
                ms.Position = 0;
                 return ms.GetBuffer();
                #endregion
                #region// new code
                //MemoryStream ms = new MemoryStream();
                //IFormatter formatter = new BinaryFormatter();
                //formatter.Serialize(ms, o);
                //byte[] bs = ms.GetBuffer();
                //ms.Seek(0, SeekOrigin.Begin);
               // return bs;
                #endregion
            }
            catch { return null; }
        }
Client 端 反序列化代码:  public  DataSet getDataSet(byte[] getobjectBytes)
        {
            try
            {
                #region//old code
                BinaryFormatter bf = new BinaryFormatter();
                bf.TypeFormat = System.Runtime.Serialization.Formatters.FormatterTypeStyle.TypesWhenNeeded;
                MemoryStream ms = new MemoryStream(getobjectBytes);
                DataSet ds = (DataSet)bf.Deserialize(ms);
                #endregion                #region//new code
                //IFormatter formatter2 = new BinaryFormatter();
                //MemoryStream ms2 = new MemoryStream();
                //ms2.Write(getobjectBytes, 0, getobjectBytes.Length);
                //ms2.Seek(0, SeekOrigin.Begin);
                //DataSet  ds = (DataSet )formatter2.Deserialize(ms2);
                #endregion                return ds;
            }
            catch { return null; }
        }
不管是用 Old Code 配合,还是New code 配合使用,都出现如上情况。求解中。。

解决方案 »

  1.   

    反序列化代码问题
    MemoryStream ms = new MemoryStream(data);
    ms.Position=0
    BinaryFormatter formatter = new BinaryFormatter();
    obj = formatter.Deserialize(ms);
      

  2.   

    MemoryStream ms = new MemoryStream(data); 正确执行后,ms.Position自然就是0(跟踪代码可以看的很清楚).没有必要再ms.Position=0。错误依旧。
      

  3.   

    在反序列化之前  先检查接受到的byte数据是否完整
      

  4.   

    已经检查了,网络传输部分没有问题。跟踪到的Server 和Client 上的数据完全一直。
      

  5.   

    同样的网络传输,同一个project,还有调用Delphi dll 处理数据的模块,delphi的模块正常。所以可以肯定网络传输是没有问题的。
      

  6.   

    我正在考虑这个 要求。
    不知道兄台 指的对象版本 作何解释。
    我这里目前的情况是 server/client 都是在VS2010(选用.NET2.0环境)环境,处在同一个电脑上(我本机),SQLserver也在我本机(sql2000)(网络server也试验过,报同样问题)。我还有一个很大的不解:如果真是存在问题,为什么会有时候正确执行(client端正常处理所有过程),有时候又不能执行,报出那个错误呢?
      

  7.   


    这个错是偶尔报出的。
     索引位置 不定,大概范围是20~150之间,都有可能。[FF]这个值每次都这样提示,每次我跟踪数据看到的都不是[FF],见图中示例为57.
    ms的数据是从socket接收过来的。
    不是每次都有这个错误,是偶尔报出。如果我加快网络请求(点一次请求server端发一次序列化好的dataset数据),这个错误出现的概率就大很多(也不是每次都报错),还有可能报另一个错误“调用目标发生异常”
    难道问题还在网络数据接收吗?
    我还没追查网络数据。测试表明,如果是小数据,table 4列 top100 以内,几乎不报任何错误(不管请求速度再快),如果是稍大的数据 table 4列 top8888左右(跨度2000),很容易出现上述错误,哪怕请求的速度很一般(正常速度点击button事件请求)请教各位朋友,帮我分析一下。
      

  8.   

    我贴出我的 网络传输代码
    server端
                #region//自动识别长度发送数据
                public static int SendData(Socket socket, byte[] buffer, int outTime,string ForSendDataOnly)
                {
                    if (socket == null || socket.Connected == false)
                    {
                        Log.WriteLog("参数socket 为null,或者未连接到远程计算机");
                      //  throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
                    }
                    if (buffer == null || buffer.Length == 0)
                    {
                        Log.WriteLog("参数buffer 为null ,或者长度为 0");
                       // throw new ArgumentException("参数buffer 为null ,或者长度为 0");
                    }                #region//自动识别并发送长度
                    int len = buffer.Length;
                    byte[] btLen = Encoding.UTF8.GetBytes(len.ToString()+"|");
                    byte[] btLenForSend = new byte[512];
                    btLen.CopyTo(btLenForSend, 0);
                    socket.Send(btLenForSend);
                    #endregion
                    int flag = 0;
                    try
                    {
                        int left = buffer.Length;
                        int sndLen = 0;                    while (true)
                        {
                            //if ((socket.Poll(outTime * 1000000, SelectMode.SelectWrite) == true))
                            //{    
                            try
                            {
                                // 收集了足够多的传出数据后开始发送   
                                sndLen = socket.Send(buffer, sndLen, left, SocketFlags.None);
                                left -= sndLen;
                                if (left == 0)
                                {                                        // 数据已经全部发送   
                                    flag = 0;
                                    break;
                                }
                                else
                                {
                                    if (sndLen > 0)
                                    {                                    // 数据部分已经被发送   
                                        continue;
                                    }
                                    else
                                    {                                                // 发送数据发生错误   
                                        flag = -2;
                                        break;
                                    }
                                }
                            }
                            catch 
                            {
                                flag = -1;
                                break;
                            }
                            //else
                            //{                                                        // 超时退出   
                            //    flag = -1;
                            //    break;
                            //}
                        }
                    }
                    catch (SocketException e)
                    {
                        Log.WriteLog(e);
                        flag = -3;
                    }
                    return flag;
                }
                #endregion
    Client 端 接收数据代码       #region//自动识别长度接收数据
           public    static   int temFlg = 0;
                public static byte []  RecvData(Socket socket, byte[] buffer, int outTime,string forDataOnly)
                {
                    if (socket == null || socket.Connected == false)
                    {
                        Log.WriteLog("参数socket 为null,或者未连接到远程计算机");
                        // throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
                    }
                    if (buffer == null || buffer.Length == 0)
                    {
                        Log.WriteLog("参数buffer 为null ,或者长度为 0");
                        //throw new ArgumentException("参数buffer 为null ,或者长度为 0");
                    }
                    #region//接长度并自动调整接收内存byte[]的大小
                    int btlenInt = BufferAutoLength(socket);
                    buffer = new byte[btlenInt];                #endregion
                    buffer.Initialize();
                    int left = buffer.Length;
                    int curRcv = 0;
                    int flag = 0;                try
                    {
                        while (true)
                        {
                            //if (socket.Poll(outTime * 1000000, SelectMode.SelectRead))
                            //{   
                            try
                            {
                                // 已经有数据等待接收   
                                curRcv = socket.Receive(buffer, curRcv, left, SocketFlags.None);
                                left -= curRcv;
                                if (left == 0)
                                {                                    // 数据已经全部接收    
                                    flag = 0;
                                    break;
                                }
                                else
                                {
                                    if (curRcv > 0)
                                    {                                // 数据已经部分接收   
                                        continue;
                                    }
                                    else
                                    {                                            // 出现错误   
                                        flag = -2;
                                        break;
                                    }
                                }
                            }
                            catch
                            {
                                flag = -1;
                                break;
                            }
                            //}
                            //else
                            //{                                                    // 超时退出                           //}
                        }
                    }
                    catch (SocketException e)
                    {
                        Log.WriteLog(e);
                        flag = -3;
                    }
                    //return flag ; ;
                    temFlg = flag;
                    return buffer;
                }            private static int BufferAutoLength(Socket socket)
                {
                    byte[] btlen = new byte[512];
                    socket.Receive(btlen);
                    string btlenStr = Encoding.UTF8.GetString(btlen).Split(new char[] { '|' })[0];
                                   int btlenInt = 0;
                    try { btlenInt = Convert.ToInt32(btlenStr); }
                    catch { Log.WriteLog("接收长度失败"); }
                    return btlenInt;
                }
                #endregion
    原来使用了 if (socket.Poll(outTime * 1000000, SelectMode.SelectRead)),CS两端都用了这个判断,后来改成现在的 try{}catch{}有什么问题,请提示。
      

  9.   

    好乱的代码,lz是写c++的吧?c#程序员不会写这么乱的socket代码吧!
      

  10.   

    这话讲的,当心CPP的程序员来啐你啊
      

  11.   


    又跟踪了一下错误。catch 套try,两次捕获的错误类型不一致。还在检查,没找到错误根。
      

  12.   

    TCP/IP协议不可能出现网络错误接收
    客户端给服务器端发送数据的时候,如果数据比较大服务器端一次是接收不了的
    得分几次接收  明白?
      

  13.   

    最后查明,还是传输模块出了问题。
    序列化和反序列化都没有问题。
    之前报出的种种错误均是由网络传输数据错乱造成的。
    现贴出 修改过的传输代码
    Server端(发送代码)  #region//自动识别长度发送数据
                public static int SendData(Socket socket, byte[] buffer, int outTime,string ForSendDataOnly)
                {
                    if (socket == null || socket.Connected == false)
                    {
                        Log.WriteLog("参数socket 为null,或者未连接到远程计算机");
                      //  throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
                    }
                    if (buffer == null || buffer.Length == 0)
                    {
                        Log.WriteLog("参数buffer 为null ,或者长度为 0");
                       // throw new ArgumentException("参数buffer 为null ,或者长度为 0");
                    }                #region//自动识别并发送长度
                    int len = buffer.Length;
                    byte[] btLen = Encoding.UTF8.GetBytes(len.ToString()+"|");
                    byte[] btLenForSend = new byte[512];
                    btLen.CopyTo(btLenForSend, 0);
                    socket.Send(btLenForSend);
                    #endregion
                    int flag = 0;
                    try
                    {
                        int left = buffer.Length;
                        int sndLen = 0;
                        int curSendlen = 0;                    while (true)
                        {
                            //if ((socket.Poll(outTime * 1000000, SelectMode.SelectWrite) == true))
                            //{    
                            try
                            {
                                // 收集了足够多的传出数据后开始发送   
                                curSendlen  = socket.Send(buffer, sndLen, left, SocketFlags.None);
                                sndLen += curSendlen;
                               // left -= sndLen;
                                left -= curSendlen;
                                if (left == 0)
                                {                                        // 数据已经全部发送   
                                    flag = 0;
                                    Ip.TCPtrance.Log.WriteControlText("【√】网络正确发送(flag = 0)" + "  " + " 发送结果状态【" + flag.ToString() + "】  ", Form1.richTextBox1);
                                    break;
                                }
                                else
                                {
                                    if (curSendlen > 0)
                                    {                                    // 数据部分已经被发送   
                                        continue;
                                    }
                                    else
                                    {                                                // 发送数据发生错误   
                                        flag = -2;
                                        break;
                                    }
                                }
                            }
                            catch 
                            {
                                flag = -1;
                                break;
                            }
                            //else
                            //{                                                        // 超时退出   
                            //    flag = -1;
                            //    break;
                            //}
                        }
                    }
                    catch (SocketException e)
                    {
                        Log.WriteLog(e);
                        flag = -3;
                    }
                    return flag;
                }
                #endregionClient端(接收数据)  #region//自动识别长度接收数据
           public    static   int temFlg = 0;
                public static byte []  RecvData(Socket socket, byte[] buffer, int outTime,string forDataOnly)
                {
                    if (socket == null || socket.Connected == false)
                    {
                        Log.WriteLog("参数socket 为null,或者未连接到远程计算机");
                        // throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
                    }
                    if (buffer == null || buffer.Length == 0)
                    {
                        Log.WriteLog("参数buffer 为null ,或者长度为 0");
                        //throw new ArgumentException("参数buffer 为null ,或者长度为 0");
                    }
                    #region//接长度并自动调整接收内存byte[]的大小
                    int btlenInt = BufferAutoLength(socket);
                    buffer = new byte[btlenInt];                #endregion
                    buffer.Initialize();
                    int left = buffer.Length;
                    int curRcv = 0;
                    int Rcvlen = 0;
                    int flag = 0;
                    int recTimes = 0;
                    try
                    {
                        while (true)
                        {
                            //if (socket.Poll(outTime * 1000000, SelectMode.SelectRead))
                            //{   
                            try
                            {
                                // 已经有数据等待接收   
                                curRcv = socket.Receive(buffer, Rcvlen, left, SocketFlags.None);
                                recTimes++;
                                left -= curRcv;
                                Rcvlen += curRcv;
                                if (left == 0)
                                {                                    // 数据已经全部接收    
                                    flag = 0;
                                    Ip.TCPtrance.Log.WriteControlText("【√】网络正确接收(flag = 0)" + "  " + " 发送结果状态【" + flag.ToString() + "】  ", Form1.richTextBox1);
                                    break;
                                }
                                else
                                {
                                    if (curRcv > 0)
                                    {                                // 数据已经部分接收   
                                        continue;
                                    }
                                    else
                                    {                                            // 出现错误                                       flag = -2;
                                        Ip.TCPtrance.Log.WriteControlText("【×】网络错误接收(flag = -2)" + "  " + " 发送结果状态【" + flag.ToString() + "】  ", Form1.richTextBox1);                                    break;
                                    }
                                }
                            }
                            catch
                            {
                                flag = -1;
                                Ip.TCPtrance.Log.WriteControlText("【×】网络错误接收(flag = -1)" + "  " + " 发送结果状态【" + flag.ToString() + "】  ", Form1.richTextBox1);
                                break;
                            }
                            //}
                            //else
                            //{                                                    // 超时退出                           //}
                        }
                    }
                    catch (SocketException e)
                    {
                        Log.WriteLog(e);
                        flag = -3;
                    }
                    //return flag ; ;
                    temFlg = flag;
                    Ip.TCPtrance.Log.WriteControlText("【 】网络接收次数 =" + "  " + " 【" + recTimes.ToString() + "】  ", Form1.richTextBox1);
                    return buffer;
                }            private static int BufferAutoLength(Socket socket)
                {
                    byte[] btlen = new byte[512];
                    socket.Receive(btlen);
                    string btlenStr = Encoding.UTF8.GetString(btlen).Split(new char[] { '|' })[0];
                    //while (btlenStr == "HBstoped")
                    //{
                    //    socket.Receive(btlen);
                    //    btlenStr = Encoding.UTF8.GetString(btlen).Split(new char[] { '|' })[0];
                    //}
                    int btlenInt = 0;
                    try { btlenInt = Convert.ToInt32(btlenStr); }
                    catch { Log.WriteLog("接收长度失败"); }
                    return btlenInt;
                }
              
                #endregion
    多谢各位支持。散分。