我现在用Socket接收客户端发来的对象数据,但是对象的内容是变化的,可大可小,如果超过了我服务端的buffer大小就会处理出错,请问怎样让接收时的buffer大小自己适应发过来的数据?

解决方案 »

  1.   


    byte[] recvBytes = new byte[5000000];
    int bytes = socket.Receive(recvBytes, recvBytes.Length, 0);//接收时设置
      

  2.   

    即使1k的buffer也可以接受1G大的一个消息。Receive应该是在一个循环中,一个buffer一个buffer地循环接收数据流。给你一桶水,然后给你一个水杯,你会把桶里的水舀赶紧吗?
      

  3.   


    public int Receive(
        byte[] buffer,
        int offset,
        int size,
        SocketFlags socketFlags
    )
    size是最多要接收的数量
      

  4.   

    你所看到的服务器千千万万,比如我们现在用到的web服务器。它的buffer能有多大?服务器端还是真正当作一个产品去设计、搞清其内部机制为好。
      

  5.   


    我也是希望是这样的方式,但是用SocketAsyncEventArgs有没有可能实现这个方式?
      

  6.   

    你的想法就不对。
    有些东西是socket必须面对的,不是能逃避掉的
    很多方法都可以很好的处理你说的问题。。合适的发送数据量、合适的间隔时间、数据的自我容错能力等等
      

  7.   

    说这么多,没有一个是实质性的可以帮我解决这个问题的,可能我的问题不够明确,
    我就是想用SocketAsyncEventArgs来解决这个传输中Buffer容量大小不一致而导致数据被截断的问题,
    我是通过Socket来传递序列化成二进制的对象,对象的数据量是变化的,序列化的大小也会不同,如何保证我的对象数据传递正确?
    最好有源码,例子..
      

  8.   

    初始化一个buffer的大小,因为socket数据包每次发送的数据量是有大小限制的,64k大小就ok了
      

  9.   


    机制就是这样的 当有数据的时候通知你, 并告诉你本次接收到多少数据. 这个数据可能不是一个包.有可能是2个包 或者半个包.必须自己写一个类来处理这些包,进行拆分和组合工作.tcp如果使用断开式,则不需要太过考虑客户端和服务器的数据传输问题.
    如果是连接式 就必须考虑了.
      

  10.   

    如果要动态接收数据的话可以考虑不要用Receive,改用NetworkStream来接收            NetworkStream stream = new NetworkStream(client);
                byte[] send = Encoding.UTF8.GetBytes("客户端==>流测试");
                stream.Write(send, 0, send.Length);
                List<byte> receive = new List<byte>();
                while (true)
                {
                    int oneByte = stream.ReadByte();
                    if (oneByte == -1)
                        break;
                    receive.Add(Convert.ToByte(oneByte));
                }
                string text = Encoding.UTF8.GetString(receive.ToArray());
                this.Text = text;
      

  11.   

    你不可能预测到接收数据的长度,因此你不必初始化一个很大的数组。
    无论数组有多小,你只需要循环的读,就可以取得所有数据:Byte[] bytesReceived = new Byte[256];
    int bytes = 0;
    string msg = string.Empty;// The following will block until te page is transmitted.
    do {
        bytes = s.Receive(bytesReceived, bytesReceived.Length, 0);  
        msg = msg + Encoding.ASCII.GetString(bytesReceived, 0, bytes); 
    }
    while (bytes > 0);
      

  12.   

    先接受长度,可以new一个适当的数组。
    也可以输出到某个Stream中。
      

  13.   


    这种方法遇到中文的情况就有可能发生截断产生乱码把这倒是。可以换成List<byte>,循环结束后再转码成字符串。
      

  14.   

    楼主应该是用 tcp 接收数据的吧,那我描述一下正确的处理方法:
    1 receive 的时候 buffer 的大小无所谓,另外新建一个 memorystream,接收了放里面。
       如果接收异常,或者接收到0长度的数据,关闭连接并退出。
    2 必须有一个方法判断 memorystream 里面是否有完整的数据包,如果没有则回 1 继续接收。
    3 如果已经有完整的数据包,进行处理,并记下数据包的大小
    4 重新新建 memorystream,如果接收的数据大于数据包的大小,
      将剩余未处理的数据放入,回到 1 继续接收。
      

  15.   

    receive是需要循环接收的,buff设置太大没用处,因为有MTU存在,一般MTU是在1.5K左右,超过1.5K的包会被自动分包发送的,我之前测试的,超过1.5K的包发到接收端,基本就会被拆成2个包,2次receive才能接收全部数据。