【问题标题】:Serializing a manually written code序列化手动编写的代码
【发布时间】:2015-09-19 12:04:00
【问题描述】:

我在从客户端接收文件时遇到问题。有人建议我应该使用二进制序列化来发送和接收流中的消息。你能给我一些关于我应该如何序列化它的想法吗?不久前我刚刚了解了序列化,所以我对如何将它与我的程序关联起来感到很困惑。

这是“应该”序列化的客户端

 public void sendthedata()
        {
            if (!_timer.Enabled) // If timer is not running send data and start refresh interval
            {
                SendData();
                _timer.Enabled = true;
            }
            else // Stop timer to prevent further refreshing
            {
                _timer.Enabled = false;
            }
        }
        private List<int> listedProcesses = new List<int>();
        private void SendData()
        {
            String processID = "";
            String processName = "";
            String processPath = "";
            String processFileName = "";
            String processMachinename = "";

            listBox1.BeginUpdate();
            try
            {   
                piis = GetAllProcessInfos();
                for (int i = 0; i < piis.Count; i++)
                {
                    try
                    {
                        if (!listedProcesses.Contains(piis[i].Id)) //placed this on a list to avoid redundancy
                        {
                            listedProcesses.Add(piis[i].Id);
                            processID = piis[i].Id.ToString();
                            processName = piis[i].Name.ToString();
                            processPath = piis[i].Path.ToString();
                            processFileName = piis[i].FileName.ToString();
                            processMachinename = piis[i].Machinename.ToString();
                            output.Text += "\n\nSENT DATA : \n\t" + processFileName + "\n\t" + processMachinename + "\n\t" + processID + "\n\t" + processName + "\n\t" + processPath + "\n";
                        }

                    }
                    catch (Exception ex)
                    {
                        wait.Abort();
                        output.Text += "Error..... " + ex.StackTrace;

                    }

                    NetworkStream ns = tcpclnt.GetStream();
                    String data = "";
                    data = "--++" + processFileName + " " +  processMachinename + " "  + processID + " " + processPath;
                    if (ns.CanWrite)
                    {
                        byte[] bf = new ASCIIEncoding().GetBytes(data);
                        ns.Write(bf, 0, bf.Length);
                        ns.Flush();
                    }
                }
            }
            finally
            {
                listBox1.EndUpdate();
            } 
        }

并在服务器中反序列化

private void recieveData()
    {
        NetworkStream nStream = tcpClient.GetStream();
        ASCIIEncoding ascii = null;
        while (!stopRecieving)
        {
            if (nStream.CanRead)
            {
                byte[] buffer = new byte[1024];
                nStream.Read(buffer, 0, buffer.Length);
                ascii = new ASCIIEncoding();
                recvDt = ascii.GetString(buffer);
                /*Received message checks if it has +@@+ then the ip is disconnected*/
                bool f = false;
                f = recvDt.Contains("+@@+");
                if (f)
                {
                    string d = "+@@+";
                    recvDt = recvDt.TrimStart(d.ToCharArray());
                    clientDis();
                    stopRecieving = true;
                }

                //else if (recvDt.Contains("^^"))
                //{
                //    new Transmit_File().transfer_file(file, ipselected);
                //}
                /* ++-- shutsdown/restrt/logoff/abort*/
                else if (recvDt.Contains("++--"))
                {
                    string d = "++--";
                    recvDt = recvDt.TrimStart(d.ToCharArray());
                    this.Invoke(new rcvData(addToOutput));
                    clientDis();
                }
                /*--++ Normal msg*/
                else if (recvDt.Contains("--++"))
                {
                    string d = "--++";
                    recvDt = recvDt.TrimStart(d.ToCharArray());
                    this.Invoke(new rcvData(addToOutput));

                }
            }
            Thread.Sleep(1000);
        }

    }

    public void addToOutput()
    {
        if (recvDt != null && recvDt != "")
        {

            output.Text += "\n Received Data : " + recvDt;
            recvDt = null;


        }

    }

谢谢。

【问题讨论】:

    标签: c# .net winforms serialization client-server


    【解决方案1】:

    序列化一段数据时需要遵循一些规则。 将数据转换为字节很容易,但要考虑如何在另一端重构数据。假设服务器对您发送的内容一无所知。

    在您的序列化器中,您只需将几个字符串转换为 byte[] 并将其发送过来。示例:

    string x = "abcdef";
    string y = "ghijk";
    
    var bytes = Encoding.Ascii.GetBytes(x + y);
    

    服务器收到:"abcdefghijk";

    服务器是否可以确定和重构字符串 x 和 y? 由于服务器不知道 x 和 y 的长度:没有。

    有办法解决这个问题:

    1. 使用固定长度的字段。在我的示例中,x 应始终为 6 个字符,y 应始终为 5 个字符。然后在服务器上解码变得像

      字符串 x = data.Substring(0, 6) 字符串 y = data.Substring(6, 5)

    2. 在字段之间使用分隔符。如果你熟悉 cvs,',' 会分割字段。然而,这有它的缺点,如何处理字符串中某处的“,”?发送过来的数据类似于“abcdef,ghijk

    3. 在字段内容之前发送每个字段的大小。 一种天真的方法只是为了澄清:字符串 x 将发送为 '6abcdef' 和 y 发送为 '5ghijk'

    手工做所有这些事情会变得很麻烦,而且我只有在真正需要时才会考虑这样做。

    我会求助于在这个主题上做得很好的现有框架:

    Json.net

    protobuf ported by Jon skeet

    在这种情况下,我将首先创建一个类来定义发送到服务器的数据而不是一堆字符串:

    class ProcessInfo{
        public string ProcessID {get;set;}
        public string ProcessName {get;set;}
        public string ProcessPath {get;set;}
        public string ProcessFileName {get;set;}
        public string ProcessMachinename {get;set;}
    };
    

    使用 Json 序列化这个:

    var procinfo = new ProcessInfo{
                       ProcessId = "1",
                       ...
                   };
    var serialised = JsonConvert.SerializeObject(procinfo);
    var bytes = Encoding.Utf8.GetBytes(serialised);
    ns.Write(bytes, 0, bytes.Length);
    

    并通过以下方式在服务器上恢复它:

    var procInfo = JsonConvert.DeserializeObject<ProcessInfo>(json);
    

    【讨论】:

    • json 会是不同的文件吗?
    • 有json的命名空间还是可以直接编码成windows窗体?
    • 使用nuget怎么样:Install-Package Newtonsoft.Json
    • hmm.. 我真的不知道 json 但我会调查它。
    猜你喜欢
    • 2018-03-02
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    相关资源
    最近更新 更多