Brandon Lewis

Brandon Lewis

  • NA
  • 527
  • 125.8k

Serializing and Deserializing List Across Network

Jan 29 2008 4:25 PM
I have the following code:

public class ChatClientManager
{
    private List<ChatClient> clientList = new
        List<ChatClient>();
    private TcpListener clientListener;
    private Thread listeningThread;

    public ChatClientManager(string ipAddress, int port)
    {
        //Creates the listener and listening thread.
        clientListner = new
            TcpListener(IPAddress.Parse(ipAddress),
            port);
        listeningThread = new Thread(ListenForUsers);
    }

    private void Listen()
    {
        //Starts listening for new clients.
        listeningThread.Start();
    }

    private void ListenForUsers()
    {
        //Creates an ample byte array to
        //store client system message.

        byte[] data = new byte[255];

        //Ugly way to do it, but it works for now.
        while(true)
        {
            //Clear the old data from the byte array.
            ClearBuffer(ref data);   
       
            //Wait for a new connection attempt
            Socket newSock =
                clientListener.AcceptSocket();

            //Receive the initial log on string.
            newSock.Receive(data);

            //Add the client to the list.
            clientList.Add(new
                ChatClient(
                GetUserName(Encoding.ASCII.GetString(data)),
                newSock));
        }
    }

    private void SendFriendsList(ChatClient chatClient)
    {
        //Create a binary formatter and
        //memory stream to serialize the list.

        BinaryFormatter bSerializer = new BinaryFormatter();
        MemoryStream listSerialStream = new MemoryStream();

        //Serialize the list to the stream
        bSerializer.Serialize(
            listSerialStream, GetOnlineUsers());
   
        //Send the list.
        chatClient.ConnectedSocket.Send(
            listSerialStream.ToArray());
    }

    private string GetUserName(string message)
    {
        //Make sure the initial message is a log on message.
        if(message.Length > 11)
            return message.Subscript(11, message.Length -11);
        else
            throw new
                ArgumentException("Initial logon
                message too short to contain user
                name.");

        //This method is imperfect and
        //will be touched up later.
        //It is the least of my issues :)

    }

    private void ClearBuffer(ref byte[] data)
    {
        //Clear the byte array of old data.
        for(int i = 0; i < data.Length; i++)
            data[i] = 0;
    }

    private List<string> GetOnlineUsers()
    {
        //Create a list of online users from the client list.
        List<string> currentUsers = new List<string>();

        foreach(ChatClient client in clientList)
            currentUsers.Add(client.UserName);

        return currentUsers;
    }
}

//Pretty self explantory.
public class ChatClient
{
    private string userName = String.Empty;
    private Socket socket;

    public ChatClient(string userName, Socket socket)
    {
        this.userName = userName;
        this.socket = socket;
    }

    public string UserName
    {
        get { return this.userName; }
    }

    public Socket ConnectedSocket
    {
        get { return this.socket; }
    }
}

My problem is that it serializes the data to the memory stream just fine and sends it, but when the client attempts to deserialize it on the other side, it comes up with an "End of Stream was encountered before parsing was completed." exception. Ive tried sending the size of the stream ahead of time, and Ive tried creating a large byte array, 1000 indices, to hold this data, and it still gives me the error. Here is the method that parses the received List<string>:

private List<string> GetFriendsList()
{
    byte[] friendData = new byte[1000];

    BinaryFormatter bDeserializer = new BinaryFormatter();
    MemoryStream memStream = new MemoryStream();

    socket.Receive(friendData);

    memStream.Write(friendData);

    //The exception occurs here.
    return bDeserializer.Deserialize(memStream);
}

Any ideas?

Answers (2)