C#TcpClient:使用分隔符发送序列化的对象?
基于序列化(在这里提到https://stackoverflow.com/a/7849374/985798 )我正在尝试重新构build我的小型TCP应用程序,直到现在使用string消息。
但是我遇到了一个小问题,我想知道你会推荐我使用什么解决scheme:
如果我试图在一个很小的时间间隔内发送多个消息,它们将被合并到“队列”中,客户端将同时收到两个消息,最终会得到一个单独的对象。 在过去,我用一个string分隔符“| end |”解决了这个问题 我能够分割它并在foreach循环中处理它。
这是一个好方法吗? 你将如何解决基于序列化的对象字节数组的问题? 你会使用一个byte[]
分隔符或使用另一种解决scheme?
以下是使用Json.Net在客户端和服务器之间发送对象的通用示例。 它使用NewLine char作为分隔符。 所以你只需要从networkingstream创buildStreamReader和StreamWriter,并使用ReadLine和WriteLine方法….
(PS:由于Json.Net在序列化中转义NewLine char,包含它的消息不会导致问题…)
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(); });
你甚至不需要在你的情况下分隔符,所有你想要做的是传递一个对象的块。 我会build议去比XML序列化轻一点,比如JSON。
var objectJson = new JavaScriptSerializer().Serialize(myObject);
这会给你一个格式的string
{ "Member1": "Value", "Member2": [ "Value1", "Value2" ], ...etc }
所有你需要做的是不断合并块,直到你有一个完整的对象然后调用
var object = new JavaScriptSerializer().Deserialize<MyObject>(objectJson);
另一方面。