我有一个客户端服务器应用程序,其中服务器和客户端需要通过网络发送和接收自定义类的对象.我正在使用TcpClient类传输数据.我正在序列化发送方的对象,并将结果的字节流发送到接收方.但是在接收端,当我尝试取消序列化接收的字节时,它会引发序列化异常,其细节是:
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,而您的数据可能更大
或更小.
您只依赖于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); }