C#TcpClient:使用分隔符发送序列化对象?

时间:2014-02-02 11:48:04

标签: c# serialization tcpclient

基于序列化(这里提到https://stackoverflow.com/a/7849374/985798)我试图重新设计我的小型tcp应用程序,直到现在才使用字符串消息。

但我遇到了一个小问题,我想知道你建议我使用什么解决方案:

如果我尝试在很短的时间间隔内发送多条消息,它们将合并到“队列”中,客户端将同时接收这两条消息,这将最终导致单个损坏的对象。在过去,我用字符串分隔符“| end |”解决了这个问题。我能够将它拆分并在foreach循环中处理它。

这是一个好方法吗?您将如何基于序列化对象字节数组解决该问题?您会使用byte[]分隔符还是使用其他解决方案?

2 个答案:

答案 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);

另一方面。