Click here to Skip to main content
15,886,832 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have achieved sending message client -> server and actually connecting many clients simultaneously. But what I want to do is i.e. connect 2 clients and make them chat between themselves. And if 3rd client connects - then so he starts chatting with both other clients.

By now I am on the stage of chatting client->server->client separately from another c->s->c. What happens is - I run client1 and everything is OK. Then I run client2 and with it everything is OK, but the 1st client stops working and then the first message I acquire on the 2nd client is the last message that I sent from client1 (but that didn't actually receive back to it from server).
So I suppose there's problem with the streams - that the 2 clients somehow acquire each-other's streams.
Here is the some parts of the server (relevant ones):

C#
class TheServer
    {
        private TcpListener tcpListener;
        private Thread threadListener;
        TheMessage msg;
        public TcpClient[] clientList = new TcpClient[100];
        private int n = 0;

        public void StartServer()
        {
            try
            {
                this.tcpListener = new TcpListener(IPAddress.Any, 8000);
                this.threadListener = new Thread(new ThreadStart(ListenForClients));
                this.threadListener.Start();

                Console.WriteLine("Local end point: " + tcpListener.LocalEndpoint);
            }
            catch (Exception e)
            {
                throw;
            }
        }

        private void ListenForClients()
        {
            this.tcpListener.Start();

            while(true)
            {
                // block until a client has connected to the server
                TcpClient client = this.tcpListener.AcceptTcpClient();
                if (n == 0)
                {
                    clientList[0] = client;
                }
                else
                {
                    n++;
                    clientList[n] = client;
                }

                // create thread to handle communication with connected client
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(clientList[n]);

            }
        }

        private void HandleClientComm(object client)
        {
            TcpClient tcpClient = (TcpClient)client;
            NetworkStream stm = clientList[n].GetStream();
            msg = new TheMessage();

            while (true)
            {
                Byte[] bSize = new Byte[sizeof(Int32)];
                stm.Read(bSize, 0, bSize.Length);

                Byte[] bData = new Byte[BitConverter.ToInt32(bSize, 0)];
                stm.Read(bData, 0, bData.Length);

                msg = XmlRefactorServer.ByteArrayToObject<TheMessage>(bData);
                String str = msg.Message;
                Console.WriteLine(str);
                stm.Flush();

                // send back to client
                msg.Message = str;
                Byte[] bDataBack = XmlRefactorServer.ObjectToByteArray<TheMessage>(msg);
                
                stm = clientList[n].GetStream();
                
                Byte[] bSizeBack = BitConverter.GetBytes(bDataBack.Length);
                
                stm.Write(bSizeBack, 0, bSizeBack.Length);
                stm.Write(bDataBack, 0, bDataBack.Length);
                stm.Flush();

            }

            tcpClient.Close();

        }


HandleClientComm(object client) is handling the receive-send operations.

And here is the client side code part, that handles the receive-send operations:
C#
while (true)
{
    msg.Message = Console.ReadLine();
    Byte[] bData = XmlRefacrotClient.ObjectToByteArray<TheMessage>(msg);

    Stream stm = client.GetStream();
    Byte[] bSize = BitConverter.GetBytes(bData.Length);
    stm.Write(bSize, 0, bSize.Length);
    stm.Write(bData, 0, bData.Length);
    stm.Flush();
    Console.WriteLine("Sent to server!");

    // reading back from server
    Console.WriteLine("Received from server!");
    Byte[] bSizeBack = new Byte[sizeof(Int32)];
    stm.Read(bSizeBack, 0, bSizeBack.Length);

    Byte[] bDataBack = new Byte[BitConverter.ToInt32(bSizeBack, 0)];
    stm.Read(bDataBack, 0, bDataBack.Length);

    msg = XmlRefacrotClient.ByteArrayToObject<TheMessage>(bDataBack);
    String str = msg.Message;
    Console.WriteLine(str);
    stm.Flush();
 }


And I get
C#
An unhandled exception of type 'System.OutOfMemoryException' occurred in
in the Server at
C#
Byte[] bData = new Byte[BitConverter.ToInt32(bSize, 0)];
sooo... yeah, there's something wrong with the streams (on my opinion).

I am open for any suggestions.
Posted
Updated 28-Apr-13 20:53pm
v2

1 solution

The problem was in the beginning of HandleClientComm() and precisely:
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream stm = clientList[n].GetStream();
msg = new TheMessage();

So I had to get the stream for 'tcpClient', not not for 'clientList[n]'.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900