在TCP上对自定义类对象进行反序列化

本文关键字:对象 反序列化 自定义 TCP | 更新日期: 2023-09-27 18:11:33

我需要对通过TCP发送到服务器的对象进行反序列化,并且想知道如何确定何时接收到所需的所有数据来执行此操作?我假设这些数据不是一次性出现的;我说的对吗?如果有帮助的话,我在自定义对象中使用[Serializable()]属性和ISerializable接口。

在TCP上对自定义类对象进行反序列化

TCP提供一个字节流。正如你所怀疑的那样,你不一定会一次收到所有的消息,也不知道某个特定消息的流何时结束,所以你必须开发自己的应用程序级协议或使用现有的协议来确定这一点。

开发你自己的很简单,例如包括总字节数作为int在前四个字节,这样你就知道一旦你读了多少,直到你收到一条消息,例如:

    public static int Recieve(NetworkStream myNetworkStream, byte[] myBigBuffer)
    {
        // Read size of message being received
        var myReadBuffer = new byte[1024];
        myNetworkStream.Read(myReadBuffer, 0, sizeof(int));
        var sizeOfMessage = BitConverter.ToInt32(myReadBuffer, 0);
        // Read incoming message may be larger than the myReadBuffer size, into myBigBuffer 
        // supplied.
        //
        var numberOfBytesRead = 0;
        do
        {
            var readSize = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
            Buffer.BlockCopy(myReadBuffer, 0, myBigBuffer, numberOfBytesRead, readSize);
            numberOfBytesRead += readSize;
        }
        while (numberOfBytesRead < sizeOfMessage);
        return numberOfBytesRead;
    }

然后你需要一种方法来反序列化字节数组到/从你的对象,因为你已经标记他们Serializable你可以使用。net的BinaryFormatter

注意:你不需要以二进制形式发送对象-你可以将它们作为文本(例如Json或XML)发送,这更易于移植。如果使用二进制,你可以与发送者和接收者共享。net程序集(例如,作为。dll),这样他们就可以访问相同的类型。

或者使用另一个已经开发的应用程序级协议,该协议已经存在。net库,并负责处理所有传输/套接字/错误处理,例如protobuf或WCF,您可以使用。net附带的protobuf-net或微软的WCF库。