0

Based on serialization (mentioned here https://stackoverflow.com/a/7849374/985798) I am trying to reengineer my small tcp application, which was using a string message until now.

But I ran into a small problem and I would like to know what solution you'd recommend me to use:

If I am trying to send more than one message in a very small interval, they will be merged in the "queue" and the client will receive both messages at the same time, which will end up with a single broken object. In the past I solved this problem with a string separator "|end|" and I was able to split it and process it in a foreach loop.

Is that a good approach? How would you solve that problem based on serialized object byte arrays? Would you use a byte[] delimiter or use another solution?

3
  • What's wrong with the solution you've got at the moment? Using a predetermined delimiter seems perfectly fine to me. Commented Feb 2, 2014 at 11:56
  • 1
    Nothing wrong with it. Just curious, if there's a better way. What implemtation do you use to split them after receiving both objects? Commented Feb 2, 2014 at 11:58
  • Here is an example that uses newline as separator stackoverflow.com/questions/12721710/… Commented Feb 2, 2014 at 12:01

1 Answer 1

2

Here is a generic example to send objects between client and server using Json.Net. It uses NewLine char as separator. So All you need is to create StreamReader and StreamWriter from network streams and to use ReadLine and WriteLine methods....

(PS: Since Json.Net escapes NewLine char in serialization, messages containing it doesn't cause problems...)

void SendObject<T>(StreamWriter s, T o)
{
    s.WriteLine( JsonConvert.SerializeObject(o) );
    s.Flush();
}

T ReadObject<T>(StreamReader r)
{
    var line = r.ReadLine();
    if (line == null) return default(T);
    return JsonConvert.DeserializeObject<T>(line);
}

SemaphoreSlim serverReady = new SemaphoreSlim(0);
//SERVER
Task.Factory.StartNew(() =>
    {
        TcpListener listener = new TcpListener(IPAddress.Any, 8088);
        listener.Start();
        serverReady.Release();
        while(true)
        {
            var client = listener.AcceptTcpClient();
            Task.Factory.StartNew(() =>
                {
                    Console.WriteLine("Client connected...");
                    var reader = new StreamReader(client.GetStream());
                    var obj = ReadObject<string>( reader) ;
                    while(obj != null)
                    {
                        Console.WriteLine("[" + obj + "]");
                        obj = ReadObject<string>(reader);
                    }
                    Console.WriteLine("Client disconnected...");
                });
        }

    });


serverReady.Wait();
//CLIENT
Task.Factory.StartNew(() =>
{
    TcpClient client = new TcpClient();
    client.Connect("localhost", 8088);
    var writer = new StreamWriter(client.GetStream());
    for (int i = 0; i < 10; i++)
    {
        SendObject(writer, "test\nmessage" + i); //message containing `\n` :)
    }
    client.Close();
});
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.