theTour
theTour

Reputation: 23

Synchronization in C# networking

I have this simple tcp server class

 class Server
{
    private TcpListener tcpListener;
    private Thread listenThread;

    public Server()
    {
        this.tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 3000);
        this.listenThread = new Thread(new ThreadStart(ListenForClients));
        this.listenThread.Start();
        Console.WriteLine("Hello");
    }


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

        while (true)
        {
            //blocks until a client has connected to the server
            TcpClient client = this.tcpListener.AcceptTcpClient();

            //create a thread to handle communication 
            //with connected client
            Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
            Console.WriteLine("New connexion");
            clientThread.Start(client);
        }
    }

    private void HandleClientComm(object client)
    {
        TcpClient tcpClient = (TcpClient)client;
        NetworkStream clientStream = tcpClient.GetStream();

        Console.WriteLine("Got Stream");

        byte[] message = new byte[4096];
        int bytesRead;

        Console.WriteLine("Initializing..");
        while (true)
        {
            bytesRead = 0;

            try
            {
                //blocks until a client sends a message
                Console.WriteLine("Reading..");
                bytesRead = clientStream.Read(message, 0, 4096);
                Console.WriteLine("Received something");
            }
            catch
            {
                //a socket error has occured
                break;
            }

            if (bytesRead == 0)
            {
                //the client has disconnected from the server
                break;
            }

            //message has successfully been received
            ASCIIEncoding encoder = new ASCIIEncoding();
            Console.WriteLine(encoder.GetString(message, 0, bytesRead));

        }

        tcpClient.Close();
    }

}

I simply call it in the main function like this :

Server server = new Server();

And in a separate client program I have this class

class TheClient
{
  public void ConnectV2()
    {


        TcpClient client = new TcpClient();

        IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000);

        client.Connect(serverEndPoint);

        NetworkStream clientStream = client.GetStream();

        ASCIIEncoding encoder = new ASCIIEncoding();

        for (int i = 0; i < 20; i++)
        {

            byte[] buffer = encoder.GetBytes("Hello Server! " + i.ToString() + " ");

            Console.WriteLine("Processing..");

            clientStream.Write(buffer, 0, buffer.Length);
            clientStream.Flush();
            Console.WriteLine("Hello Server sent");
        }


    }

}

I call it in the main function like

TheClient tc = new TheClient();

tc.ConnectV2();

My problem is that the server program seems slower than the client, he don't react before the 13th, or more, message from the client :

[I can't post images because of reputation]

It reads the first dozen of messages in one go, and then reads the others one by one.

And if I make the server emit first, the client receive the message, but they both stop, like if both wait for the other to send something.

Can someone explain me this behavior ? How can I control and synchronize it ?

Upvotes: 2

Views: 1861

Answers (2)

usr
usr

Reputation: 171178

TCP is not message based. It provides a stream of bytes. It is your responsibility to separate messages. Also note, that you might receive only a part of a message in one Read call.

Here's a simple way to do that: Send the messages as individual lines. Possibly using StreamWriter. Receive the messages using StreamReader.ReadLine().

That way you can also use a more sane encoding such as Encoding.UTF8.

Besides that your code is actually fine and workable. It is extremely rare to see almost working TCP code on Stack Overflow. Most code is horribly broken. Congratulations.

Upvotes: 2

Angus Chung
Angus Chung

Reputation: 1587

It's because that your client AP is always sending data ,but your server AP cannot receive those data right away. So,those data stacked in buffer and then server AP receive all at once.

You can try:

  1. Set fixed lengths when you send or receive data.

    or

  2. Receive and split data.

Upvotes: 0

Related Questions