C # TcpClient: send serialized objects using delimiters?

Based on serialization (see here https://stackoverflow.com/questions/1377549/... ), I am trying to reengineer my small tcp application that has so far used a string message.

But I had a little problem, and I would like to know what solution you would recommend to me:

If I try to send several messages in a very small interval, they will be queued, and the client will receive both messages at the same time, which will lead to one broken object. In the past, I solved this problem with the "| end |" line separator and I was able to break it and process it in a foreach loop.

Is this a good approach? How would you solve this problem based on serialized arrays of object arrays? Are you using the byte[] delimiter or are you using a different solution?

0
source share
2 answers

Here is a general example for sending objects between client and server using Json.Net. As a separator, a NewLine char is used. So, all you need to do is create a StreamReader and StreamWriter from network streams and use the ReadLine and WriteLine methods ....

(PS: Since Json.Net escapes NewLine char in serialization, messages containing it do not 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(); }); 
+2
source

In your case, you don’t even need a separator, all you are trying to do is pass the object to pieces. I would recommend going for something a little easier than XML serialization, for example. JSON

 var objectJson = new JavaScriptSerializer().Serialize(myObject); 

This will give you a string in the format

 { "Member1": "Value", "Member2": [ "Value1", "Value2" ], ...etc } 

All you have to do is merge the pieces until you have a complete object, and then call

 var object = new JavaScriptSerializer().Deserialize<MyObject>(objectJson); 

On the other hand.

-2
source

Source: https://habr.com/ru/post/1486092/


All Articles