Client端把自定义的Report对象分成多个定长的包发送,在Server端也按同样的定长接收。但接收到包的数量总是大于发送的数量,而且虽然反序列化能成功,但从反序列化所得到的Report对象中的byte[]字段的长度比Client端发送时要长。这个byte[]是用来保存图片的,出现这种情况导致图片不能正常在Server端显示。而且在Report对象中只有这个byte[]的字段出现问题,其他3个String型的字段都没有问题。这个问题当Client端和Server端在同一台计算机上时是不会出现的,应该和网络传输有关,但我不清楚到底是哪里的问题。下面是代码,希望各位高手指点一二。Report类public class Report
    {
        public string textOne;
        public string textTwo;
        public byte[] pic;
        public string textThree;
    }
Client端代码            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ep = new IPEndPoint(Dns.GetHostEntry("12.23.5.678").AddressList[0], 9999);            socket.Connect(ep);            XmlSerializer xs = new XmlSerializer(typeof(Report));
            StringWriter sw = new StringWriter();            Report report = new Report();
            report.textOne= "qwe";
            report.textTwo= "asd";
            report.textThree= "zxc";            MemoryStream ms = new MemoryStream();
            pic.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            report.pic = ms.GetBuffer();            xs.Serialize(sw, report);
            string reportString = sw.GetStringBuilder().ToString();
            byte[] reportBytes = System.Text.Encoding.Default.GetBytes(reportString);            int pos = 0;
            int count = 0;
            while (pos < reportBytes.Length)
            {
                byte[] data = new byte[1024];
                if (reportBytes.Length - pos >= 1024)
                {
                    Array.Copy(reportBytes, pos, data, 0, 1024);
                }
                else
                {
                    Array.Copy(reportBytes, pos, data, 0, reportBytes.Length - pos);
                }
                socket.Send(data);
                count++;
                pos += 1024;
            }
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
Server端代码            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            ep = new IPEndPoint(Dns.GetHostEntry("12.23.5.678").AddressList[0], 9999);            socket.Bind(ep);
            socket.Listen(100);            Socket client = socket.Accept();            byte[] data = new byte[1024];            MemoryStream ms = new MemoryStream();
            int count = 0;
            while (client.Receive(data) > 0)
            {
                count++;
                ms.Write(data, 0, 1024);
            }
            Console.Write(count);            string stepOne = System.Text.Encoding.Default.GetString(ms.GetBuffer());            XmlSerializer ser = new XmlSerializer(typeof(Report));
            StringReader sr = new StringReader(stepOne);
            Report report = (Report)ser.Deserialize(sr);            return report;

解决方案 »

  1.   

    直接发数据是很危险的,利用一种协议发送吧,比如:SIP,或自己定义一种协议(协议头+协议体)
      

  2.   

    不是 GetBuffer(),而应该用 ToArray()。
      

  3.   

    另外,你没有必要“定长”发送接收。客户端只要一个send命令把整个reportBytes 发过去就可以了。客户端执行send之后,就等着服务器端给一个回应,然后就结束。服务器根本不需要跟客户端同样的“定长”长度,你的接收代码就可以了。在服务器端接收到信息,既你的 Console.Write(count); 代码的地方,服务器端给客户端返回一个信息(例如就是count,或者是"OK!"),然后服务端就可以断开了。你的程序只是适合单机、个人玩玩。真正的服务器程序,尽可能异步处理,包括异步Accept和异步Receive,这样才能够并行高效地处理上千个客户连接。
      

  4.   

    另外,.net封装了TcpClient/TcpListener,UdpClient、HttpListener(你可以用一个console程序来构成自己的web服务器),不要动不动就用低级的Socket,要用用高级的。