做了个类似于QQ的,之前遇到好多问题都是序列化那边报错...
我想了想 应该是接受的时候没有接完整 它才提示我错误的...
之后 我read的时候 加大了字节长度....可以了,我本地测试 所有的问题都没了
可把客户端给别人....就不行了, 想请大家帮忙 看看我这个分割 消息的方式 有什么不对么????
这个项目 要完了, 求大家帮忙看下, 我太苦恼了!!!发送消息:
//str是一条消息.....【序列化而成的字符串】
stream.Write(Encoding.Unicode.GetBytes(str), 0, Encoding.Unicode.GetBytes(str).Length);
stream.Write(Encoding.Unicode.GetBytes("|"), 0, Encoding.Unicode.GetBytes("|").Length);
接受消息 + 切割消息:
                            string data = null; //最后要切割
                            while (true)
                            {
                                byte[] buffer = new byte[5000];   //我加大这个5000的数值之后 接起来有点卡,但之前2000的话 消息接不完整
                                int bytesRec = stream.Read(buffer, 0, buffer.Length);
                                //int bytesRec = handler.Receive(bytes);
                                data += Encoding.Unicode.GetString(buffer, 0, bytesRec);
                                if (data.IndexOf("|") > -1)//这个代表接受到指定的消息,也是自己定义即可
                                {
                                    break;
                                }
                            }
  
                            string[] t = data.Split('|');       //把消息切割成多份“命令”然后进行消息处理,把一条条完整消息切割下来放在t数组里面....然后数组元素一个个提取【反序列化之后】再处理!!!!!!
总体大概就是这样
在本地吧都已经测试 没有半点问题了.... 可把客户端给别人用的时候接受了一条消息, 第二条没有接受完整就进入了反序列化...所以它提示我,反序列化格式不正确....哎,这个平台 好是好, 可是也不知道为什么,我发了 5     6条帖子 特别少人上心.....
希望如果真的会的 帮忙下吧.....谁也有需要帮忙的时候,虽然我没多少分!!!但我尽量把问题描述详细了,希望得到
满意的结果~~~~!!!

解决方案 »

  1.   

    接收时不要通过"|"来判断,如果人家聊天的时候输入了"|"怎么办?
    一般都是在数据包前四个字节写整个包的包长,接收时这样处理://接收缓冲区
    byte[] buffer = new byte[4096];
    int offset = 0;
    int count = 4;
    Socket client..........
    while(true)
    {
          int len = client.Receive(buffer, offset, count, SocketFlags.None);
          if (len != count)
          {
               offset += len;
               count -= len;
               continue;
          }
          if (sd.OffSet < 4)
          {
               int datalen = BitConverter.ToInt32(buffer, 0);
               offset = 4;
               count = datalen - 4;
               continue;
          }
          DoSomething(client, buffer, offset, count);}这篇文章希望能提供借鉴http://topic.csdn.net/u/20120710/12/dcbf2717-cd87-49b1-977f-aecf897a46b9.html
      

  2.   

    更正一下byte[] buffer = new byte[4096];
    int offset = 0;
    int count = 4;
    Socket client..........
    while(true)
    {
          int len = client.Receive(buffer, offset, count, SocketFlags.None);
          if (len != count)
          {
               offset += len;
               count -= len;
               continue;
          }           
          int datalen = BitConverter.ToInt32(buffer, 0);
          if (sd.OffSet < 4)
          {
               offset = 4;
               count = datalen - 4;
               continue;
          }
          DoSomething(client, buffer, 0, datalen);
          offset = 0;
          count = 4;
    }
      

  3.   

    还是以包的形式发送吧,设计一个包头,包头中可以存包长还可以存其他你需要的信息,然后收的时候用一个FIFO来存数据,如果发现包不全丢弃,重新发送。
      

  4.   

    指出一个小问题,
    int bytesRec = stream.Read(buffer, 0, buffer.Length);
    下面没有判断 bytesRec 等于0的情况
      

  5.   

    既然要用socket,最好把tcp/ip 和socket了解清楚,再使用
    否则,尽量使用一些封装好的框架,比如原来的remoting ,现在好像变了一个名字
      

  6.   


    我是用NetWorkStream来接收和发送的....请问这样要怎么写呢
    然后你说的4个字节我是不是可以写成NetWorkStream stream = new NetWorkStream(...);stream.Write(发送长度);
    stream.Write(发送我序列化好的东西);
      

  7.   


    如果可以的话,可否加下QQ : 4841317
    共享一下你这个程序的代码...这上面有的变量什么意思  不是很清楚  "if (sd.OffSet < 4)"
      

  8.   


    真心求代码.....这个DoSomething函数里面是怎么处理的!!
      

  9.   

    10楼的发送方式可以.
    11楼,这样接收是为了保证每次处理缓冲区的数据时都是一个完整且不冗余的数据包.通过设置接收长度并不断递增offset和递减接收长度,直至实际接收长度等于希望接收的长度。先接收四个字节的包头,再由包头得到剩余的数据长度后接收剩余的数据。因为四个字节的包头也可能不能够一次接收完毕,在判断实际接收长度等于希望接收长度后,接收到的可能是四个字节的包头,也可能是剩余的数据,所以要根据offset来判断接收到的是包头还是完整数据,offset < 4表明包头接收完毕了,重新设置长度接收包头后的数据。
      

  10.   

    楼主还是先研究下socket
    最好清楚网络通讯的协议的基本概念
    不然你怎么知道你的数据是否正确
    网络传输丢包,粘包,中断都是有可能的