C# TcpClient: Send serialized objects using separators?

心不动则不痛 提交于 2020-01-18 04:32:08

问题


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?


回答1:


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();
});


来源:https://stackoverflow.com/questions/21510204/c-sharp-tcpclient-send-serialized-objects-using-separators

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!