使用BinarySerializer进行C#TCP数据传输

时间:2018-07-27 16:10:15

标签: c# unity3d serialization tcpclient networkstream

我正在尝试使用C#TCPClient类将笔记本电脑与独立PC连接起来。

笔记本电脑正在运行一个简单的控制台应用程序,并扮演服务器的角色。

PC是Unity应用程序(带有.Net4.x Mono的2018.1.6f1)

发送代码是

public void SendData() {
    Debug.Log("Sending data");
    NetworkStream ns = client.GetStream();
    BinaryFormatter bf = new BinaryFormatter();
    TCPData data = new TCPData(true);
    using (MemoryStream ms = new MemoryStream()) {
        bf.Serialize(ms, data);
        byte[] bytes = ms.ToArray();
        ns.Write(bytes, 0, bytes.Length);
    }
}

笔记本电脑项目中使用相同的代码,不同之处在于Debug.Log()Console.WriteLine()取代

我用于数据接收

public TCPData ReceiveData() {
    Debug.Log("Waiting for Data");
    using (MemoryStream ms = new MemoryStream()) {
    byte[] buffer = new byte[2048];
        int i = stream.Read(buffer, 0, buffer.Length);
        stream.Flush();
        ms.Write(buffer, 0, buffer.Length);
        ms.Seek(0, SeekOrigin.Begin);
        BinaryFormatter bf = new BinaryFormatter();
        bf.Binder = new CustomBinder();
        TCPData receivedData = (TCPData)bf.Deserialize(ms);
        Debug.Log("Got the data");
        foreach (string s in receivedData.stuff) {
            Debug.Log(s);
        }
        return receivedData;
    }
}

双方相同,

我要传输的数据看起来像这样

[Serializable, StructLayout(LayoutKind.Sequential)]
public struct TCPData {
    public TCPData(bool predefined) {
        stuff = new string[2] { "Hello", "World" };
        ints = new List<int>() {
            0,1,2,3,4,5,6,7,8,9
        };
    }
    public string[] stuff;
    public List<int> ints;
}

自定义活页夹来自here 没有它,我得到一个组装错误

有了它我得到Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization.

现在是问题:

从PC发送到笔记本电脑-成功率100%
从笔记本电脑发送到PC的成功率达20%
(上面的例外是80%)

“有时”如何运作?
是100%还是0%?
如何使它工作?

谢谢

E:好的,感谢所有我设法增加成功机会的建议,但仍然偶尔会失败。

我发送的数据量“数据包”是正确接收时间的80%,但是在某些情况下,我从byte []获得的数字是3096224743817216(非常大),与发送的〜500相比。

我正在使用Int64数据类型。

E2:在E1中,我是分别发送数据长度数据包,现在我将它们合并,可以正确解释长度,但是现在我无法反序列化数据……每次我得到The input stream is not a valid binary format. The starting contents (in bytes) are: 00-00-00-00-00-00-04-07-54-43-50-44-61-74-61-02-00 ...

我从流中读取了前8个字节,其余的'x'是数据,在服务器上将其反序列化,对相同的数据抛出进行反序列化。

E3:通过重写流处理代码对其进行了修复,我在其中的某个地方犯了一个错误;)

1 个答案:

答案 0 :(得分:1)

NetworkStream.Read()在读取请求的字节数之前不会阻塞:

“此方法将数据读入buffer参数并返回成功读取的字节数。如果没有可读取的数据,则Read方法将返回0。Read操作将读取尽可能多的数据,最多大小由size参数指定。如果远程主机关闭连接,并且已收到所有可用数据,则Read方法立即完成并返回零字节。”

您必须

1)知道您期望多少字节

2)在Read()上循环,直到收到所需的字节为止。

如果您使用HTTP或Web套接字等高级协议,它们将为您处理此“消息框架”。如果您直接在TCP / IP上编码,那是您的责任。