Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
364 views
in Technique[技术] by (71.8m points)

c# - The input stream is not a valid binary format. Serialization issue

Hello I'm having some problems with this piece of code:

This:

public void SendRegistrationPacket()
    {
        Packet p = new Packet(PacketType.Registration, "server");
        p.Gdata.Add(id);
        clientSocket.Send(p.ToBytes());
    }

sends p.ToBytes() to this:

public Packet(byte[] packetbytes)
    {
        BinaryFormatter bf = new BinaryFormatter();
        MemoryStream ms = new MemoryStream(packetbytes);
        Packet p = (Packet)bf.Deserialize(ms);
        ms.Close();
        this.Gdata = p.Gdata;
        this.packetInt = p.packetInt;
        this.packetBool = p.packetBool;
        this.senderID = p.senderID;
        this.packetType = p.packetType;
    }

I'm getting following error at Packet p = (Packet)bf.Deserialize(ms); :

An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll Additional information: The input stream is not a valid binary format. The starting contents (in bytes) are: 35-2D-33-39-61-30-63-65-33-65-37-38-33-65-05-FB-FF ...

I have no idea what I'm doing wrong...

Could anybody help me out?

Many thanks for your time!

---- EDIT ----

Server.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServerData;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;
using Newtonsoft.Json;
using Server;

namespace Server
{
    class Server
    {

        static Socket listenerSocket;
        static List<ClientData> clients;

        static void Main(string[] args)
        {

            Console.WriteLine("Starting Server On: " + Packet.GetIP4Address());
            listenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clients = new List<ClientData>();

            IPEndPoint ip = new IPEndPoint(IPAddress.Parse(Packet.GetIP4Address()), 4242);

            listenerSocket.Bind(ip);

            Thread listenThread = new Thread(ListenThread);
            listenThread.Start();

        } //Start server


        //Listner - listens for clients trying to connect
        static void ListenThread()
        {
            while (true)
            {
                listenerSocket.Listen(0);

                clients.Add(new ClientData(listenerSocket.Accept()));

            }
        }

        //ClientData thread - receives data from each client individually
        public static void Data_IN(object cSocket)
        {
            Socket clientSocket = (Socket)cSocket;
            byte[] buffer;
            int readBytes;
            while (true)
            {
                try
                {

                    buffer = new byte[clientSocket.SendBufferSize];
                    readBytes = clientSocket.Receive(buffer);

                    if (readBytes > 0)
                    {
                        //handle data
                        Packet packet = new Packet(buffer);
                        DataManger(packet);
                    }
                }
                catch (SocketException ex)
                {
                    //Console.WriteLine("A Client Had Disconnected!");
                }
            }
        }

        //Data Manager
        public static void DataManger(Packet p)
        {
            switch (p.packetType)
            {
                case PacketType.Chat:
                    foreach (ClientData c in clients)
                    {
                        c.clientSocket.Send(p.ToBytes());
                    }
                    break;
                case PacketType.Connect:
                    //Console.WriteLine("User: "" + p.Gdata[0] + "" Has connected from IP: " + p.Gdata[1]);

                    string response = System.IO.File.ReadAllText(@"D:json.txt");//"{"one": "0","two": "45","three": "5","four": "86","five": "75","six": "32","Count": "6883197667"}";

                    response = response.Substring(1, response.Length - 2);

                    Rootobject root = JsonConvert.DeserializeObject<Rootobject>(response);

                    foreach (ClientData c in clients)
                    {
                        if (c.id == p.Gdata[1])
                        {
                            Packet packet = new Packet(PacketType.Message, "Server");
                            packet.Gdata.Add(root.one);
                            packet.Gdata.Add(root.two);
                            packet.Gdata.Add(root.three);
                            packet.Gdata.Add(root.four);
                            packet.Gdata.Add(root.five);
                            packet.Gdata.Add(root.six);
                            packet.Gdata.Add(root.Count);
                            packet.Gdata.Add(root.Found);
                            c.clientSocket.Send(packet.ToBytes());
                            break;
                        }
                    }

                    break;
                case PacketType.Message:

                    List<Rootobject> data = new List<Rootobject>();

                    data.Add(
                        new Rootobject
                        {
                            one = p.Gdata[0],
                            two = p.Gdata[1],
                            three = p.Gdata[2],
                            four = p.Gdata[3],
                            five = p.Gdata[4],
                            six = p.Gdata[5],
                            Count = p.Gdata[6],
                            Found = p.Gdata[7]
                        }
                        );

                    string json = JsonConvert.SerializeObject(data.ToArray());

                    System.IO.File.WriteAllText(@"D:json.txt", json);

                    string responseB = System.IO.File.ReadAllText(@"D:json.txt");

                    responseB = responseB.Substring(1, responseB.Length -2);

                    Rootobject rootB = JsonConvert.DeserializeObject<Rootobject>(responseB);

                    foreach (ClientData c in clients)
                    {
                        if (c.id == p.Gdata[8])
                        {
                            Packet packet = new Packet(PacketType.Message, "Server");
                            packet.Gdata.Add(rootB.one);
                            packet.Gdata.Add(rootB.two);
                            packet.Gdata.Add(rootB.three);
                            packet.Gdata.Add(rootB.four);
                            packet.Gdata.Add(rootB.five);
                            packet.Gdata.Add(rootB.six);
                            packet.Gdata.Add(rootB.Count);
                            packet.Gdata.Add(rootB.Found);
                            c.clientSocket.Send(packet.ToBytes());
                            break;
                        }
                    }

                    break;
                case PacketType.Disconnect:
                    Console.WriteLine("User: "" + p.Gdata[0] + "" Has disconnected from IP: " + p.Gdata[1]);
                    break;
            }
        }



    }
}

ClientData.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using ServerData;
using System.Runtime.Serialization.Formatters.Binary;

namespace Server
{
    class ClientData
    {

        public Socket clientSocket;
        public Thread clientThread;
        public string id;

        public ClientData()
        {
            id = Guid.NewGuid().ToString();
            clientThread = new Thread(Server.Data_IN);
            clientThread.Start(clientSocket);
            SendRegistrationPacket();
        }
        public ClientData(Socket clientSocket)
        {
            this.clientSocket = clientSocket;
            id = Guid.NewGuid().ToString();
            clientThread = new Thread(Server.Data_IN);
            clientThread.Start(clientSocket);
            SendRegistrationPacket();
        }

        public void SendRegistrationPacket()
        {
            //Packet p = new Packet(PacketType.Registration, "server");
            //p.Gdata.Add(id);
            ////clientSocket.Send(p.ToBytes());
            //BinaryFormatter bf = new BinaryFormatter();
            //MemoryStream ms = new MemoryStream();

            Packet p = new Packet(PacketType.Registration, "server");
            p.Gdata.Add(id);

            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            bf.Serialize(ms, p);
            clientSocket.Send(ms.ToArray());
        }
    }
}

Packet.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServerData;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Net;

namespace ServerData
{
    [Serializable]
    public class Packet
    {
        public List<string> Gdata;
        public int packetInt;
        public bool packetBool;
        public string senderID;
        public PacketType packetType;

        public Packet(PacketType type, string senderID)
        {
            Gdata = new List<string>();
            this.senderID = senderID;
            this.packetType = type;
        }

        public Packet(byte[] packetbytes)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream(packetbytes);
            Packet p = (Packet)bf.Deserialize(ms);
            ms.Close();
            this.Gdata = p.Gdata;
            this.packetInt = p.packetInt;
            this.packetBool = p.packetBool;
            this.senderID = p.senderID;
            this.packetType = p.packetType;
        }

        public byte[] ToBytes()
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();

            bf.Serialize(ms, this);

            byte[] bytes = ms.ToArray();
            ms.Close();

            return bytes;
        }

        public static string GetIP4Address()
        {
            IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName());

            foreach (IPAddress ip in ips)
            {
                if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    return ip.ToString();
                }
            }

            return "127.0.0.1";
        }

    }

    public enum PacketType
    {
        Registration,
        Chat,
        Connect,
        Disconnect,
        Message
    }
}

Client.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ServerData;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Security.Cryptography;

namespace Client
{
    class Client
    {
        public static Socket master;
        public static string id;

        #region MD5 Crack vars
        public static bool found = false;
        public static string charsS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQESTUVWXYZ0123456789~!@#$%^&*_-+=`|\(){}[]:;"'<>,.?/??ü???ê???aéyúíóáé";
        public static int length = 6;
       

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is from

readBytes = clientSocket.Receive(buffer);

if (readBytes > 0)
{
    //handle data
    Packet packet = new Packet(buffer);
    DataManger(packet);
}

One send from the client does not equal one receive on the server. You need "Message Frameing", your Packet only contains the first part of the data that was sent.

The easiest solution is first send the length of the byte array then have the receiving side receive only that length, allocate a buffer of that size then loop until it has fully filled the buffer.

Here is a quick example of the receiving side

private static byte[] ReadFully(Socket clientSocket, int length)
{
    int offset = 0;
    byte[] buffer = new byte[length];
    while(offset < length)
    {
        int read = clientSocket.Receive(buffer, offset, length - offset, SocketFlags.None);
        if(read = 0)
           return null; //Socket closed
        offset += read;
    }
    return buffer;
}


//read the length
byte[] lengthBuffer = ReadFully(clientSocket, 4);
if(lengthBuffer == null)
{
    //Do something about the closed connection
}
int length = BitConverter.ToInt32(lengthBuffer, 0);

//read the number of bytes specified by the length.
byte[] packetBuffer = ReadFully(clientSocket, length);

if (packetBuffer != null)
{
    //handle data
    Packet packet = new Packet(packetBuffer);
    DataManger(packet);
}

I leave it to you to do the sending side.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...