Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

serialization - C# TcpClient: Send serialized objects using separators?

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?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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
message" + i); //message containing `
` :)
    }
    client.Close();
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...