C#套接字发送序列化数据

3

我在通过TCP/IP套接字连接发送序列化数据时遇到了问题。

我的发送函数如下:

public void SendData(NetworkConnection connection, ReplicableObject ro) {
            MemoryStream ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, ro);

            ms.WriteTo(connection.TcpStream);
            connection.TcpStream.Flush();

            ms.Close();
        }

我知道目前TcpStream.Flush()并没有实际作用,但这不是我的问题。

在接收(客户端)端,读取器应该如下:

byte[] readBuffer = new byte[8192];
            worldMapStream = worldMapConnection.GetStream();
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            IsConnectedToWorldMap = true;
            while (true) {
                try {
                    do {
                        int bytes = worldMapStream.Read(readBuffer, 0, readBuffer.Length);
                        ms.Write(readBuffer, 0, bytes);
                    }
                    while (worldMapStream.DataAvailable);

                    try {
                        ReplicableObject ro = (ReplicableObject) bf.Deserialize(ms);
                        ro = ro;
                    }
                    catch (Exception e) {
                        e = e;
                    }
                }

奇怪的 ro = ro 和 e = e 行只是为了我可以添加断点。
我的问题是:读取总是失败。我遇到了一个异常,消息解释说在完成解析之前已经到达了流的末尾。现在,我知道数据可能不会一次性全部到达,但我没有在捕获异常时清除内存流,所以下一个块应该只是将剩余的数据添加到其末尾,对吧?但这似乎行不通。
那么,我做错了什么?提前致谢。
附言:我知道 WCF 是更好的选择;但不幸的是,在这个项目中我不能使用它。
1个回答

2

我们开始吧:

while (worldMapStream.DataAvailable);

应该是:

while(bytes>0);

这也意味着将 bytes 移到循环外。

DataAvailable 只是表示 "当前在 NIC 上有数据",它不会告诉你是否还有更多数据。此外,当且仅当 bytes>0 时才应该进行写入操作;说实话,在这里使用while 循环更容易 :)

接下来,在填充完ms之后,设置 ms.Position = 0 来倒回流。


对不起,我可能误解了……那么这个循环就永远不会退出了吗?因为每次从tcpstream读取字节时,字节数都会大于0;导致它返回循环的开头并重新读取? - Xenoprimate
@Motig 当关闭时,它将返回<= 0。另外,还有第二个错误-请参见编辑。 - Marc Gravell
再次问候,很抱歉回复晚了。将 ms.Position = 0 设置为前面写入新数据?有点像在最开始写单词“Hello”时先写“He”,然后重置到开头写“llo”……结果是“lloHe”? - Xenoprimate
另外,NetworkStream.Read() 是一个阻塞命令,对吧?那么它怎么可能返回除正值以外的任何东西呢? - Xenoprimate
@Motig - 在反序列化之前倒带,而不是在每次写入之后。 - Marc Gravell
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接