为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

C#
蝴蝶不菲 2020-02-03 13:41:46

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


但是我遇到了一个小问题,我想知道您建议我使用哪种解决方案:


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


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


查看完整描述

1 回答

?
慕尼黑8549860

这是一个使用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();

});


查看完整回答
反对 2020-02-03

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信