C# · 12月 30, 2021

在C#中使用Tcpclient类发送和接收自定义对象

我有一个客户端服务器应用程序,其中服务器和客户端需要通过网络发送和接收自定义类的对象.我正在使用TcpClient类传输数据.我正在序列化发送方的对象,并将结果的字节流发送到接收方.但是在接收端,当我尝试取消序列化接收的字节时,它会引发序列化异常,其细节是: @H_404_2@

The input stream is not a valid
binary format. The starting contents
(in bytes) are:
0D-0A-00-01-00-00-00-FF-FF-FF-FF-01-00-00-00-00-00

序列化对象的我的服务器代码是:

byte[] userDataBytes;MemoryStream ms = new MemoryStream();BinaryFormatter bf1 = new BinaryFormatter();bf1.Serialize(ms,new DataMessage());userDataBytes = ms.ToArray();netStream.Write(userDataBytes,userDataBytes.Length);

解除序列化的客户端代码是:

readNetStream.Read(readMsgBytes,(int)tcpServer.ReceiveBufferSize);MemoryStream ms = new MemoryStream(readMsgBytes);BinaryFormatter bf1 = new BinaryFormatter();ms.Position = 0;object rawObj = bf1.Deserialize(ms);DataMessage msgObj = (DataMessage)rawObj;

请帮助我解决这个问题,并且可能建议任何其他方法通过C#中的TcpClient在网络上传输自定义类的对象.

谢谢,
拉克什.

解决方法 在客户端接收时,您不知道要读取多少数据.
您只依赖于ReceiveBufferSize,而您的数据可能更大
或更小.

我认为这里最好的方法是发送4个字节,告诉你的客户有关传入数据的长度:

byte[] userDataLen = BitConverter.GetBytes((Int32)userDataBytes.Length);netStream.Write(userDataLen,4);netStream.Write(userDataBytes,userDataBytes.Length);

在接收端,您首先读取数据长度,然后阅读
确切的数据量.

byte[] readMsgLen = new byte[4];readNetStream.Read(readMsgLen,4);int dataLen = BitConverter.ToInt32(readMsgLen);byte[] readMsgData = new byte[dataLen];readNetStream.Read(readMsgData,dataLen);

事实上,我只是意识到,你可能需要多做一点,以确保你读取所有的数据(只是一个想法,因为我没有尝试过,但只是让你再次遇到问题,你可以尝试这个).

NetworkStream.Read()方法返回一个数字,表示它已读取的数据量.接收数据可能比RecieveBuffer大.在这种情况下,您必须循环才能读取所有数据.你必须这样做:

SafeRead(byte[] userData,int len){ int dataRead = 0; do { dataRead += readNetStream.Read(readMsgData,dataRead,len – dataRead); } while(dataRead < len);}