基于序列化(这里提到https://stackoverflow.com/a/7849374/985798)我试图重新设计我的小型tcp应用程序,直到现在才使用字符串消息。
但我遇到了一个小问题,我想知道你建议我使用什么解决方案:
如果我尝试在很短的时间间隔内发送多条消息,它们将合并到“队列”中,客户端将同时接收这两条消息,这将最终导致单个损坏的对象。在过去,我用字符串分隔符“| end |”解决了这个问题。我能够将它拆分并在foreach循环中处理它。
这是一个好方法吗?您将如何基于序列化对象字节数组解决该问题?您会使用byte[]
分隔符还是使用其他解决方案?
答案 0 :(得分:2)
这是使用Json.Net在客户端和服务器之间发送对象的一般示例。它使用NewLine char作为分隔符。所以你需要的是从网络流创建StreamReader和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();
});
答案 1 :(得分:-2)
你甚至不需要在你的情况下使用分隔符,你在这里尝试做的就是以块的形式传递一个对象。我建议选择比XML序列化更轻松的东西,例如JSON。
var objectJson = new JavaScriptSerializer().Serialize(myObject);
这会给你一个格式为
的字符串{
"Member1": "Value",
"Member2": [ "Value1", "Value2" ],
...etc
}
您需要做的就是继续合并块,直到您有一个完整的对象然后调用
var object = new JavaScriptSerializer().Deserialize<MyObject>(objectJson);
另一方面。