I have a client and server application. The server sends the file via TCP, the client accepts. That's only after the server has sent, the client cannot deserialize. Here is the function of sending a file.

public string SendFileName = null; public void SendData() { // Бостав отсылаСмого ΡƒΠ½ΠΈΠ²Π΅Ρ€ΡΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ сообщСния // 1. Π—Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ класса ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π΄Π°Π»ΡŒΠ½Π΅ΠΉΡˆΠΈΡ… Π±Π°ΠΉΡ‚ΠΎΠ² // 2. ΠžΠ±ΡŠΠ΅ΠΊΡ‚ класса ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π±Π°ΠΉΡ‚Π°Ρ… // 3. Π‘Π°ΠΉΡ‚Ρ‹ нСпосрСдствСнно Π³ΠΎΡ‚ΠΎΠ²Ρ‹Ρ… ΠΊ записи Π² Ρ„Π°ΠΉΠ» ΠΈΠ»ΠΈ для Ρ‡Π΅Π³ΠΎ-Ρ‚ΠΎ ΠΈΠ½ΠΎΠ³ΠΎ. SendInfo si = new SendInfo(); // Если Π½Π΅Ρ‚ отсылаСмого Ρ„Π°ΠΉΠ»Π° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Ρ‚ΡŒ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Π½Π΅Ρ‚ смысла. if (String.IsNullOrEmpty(SendFileName) == true) return; if (SendFileName != null) { FileInfo fi = new FileInfo(SendFileName); if (fi.Exists == true) { si.filesize = (int)fi.Length; si.filename = fi.Name; } fi = null; } BinaryFormatter bf = new BinaryFormatter(); MemoryStream ms = new MemoryStream(); bf.Serialize(ms, si); ms.Position = 0; byte[] infobuffer = new byte[ms.Length]; int r = ms.Read(infobuffer, 0, infobuffer.Length); ms.Close(); byte[] header = GetHeader(infobuffer.Length); byte[] total = new byte[header.Length + infobuffer.Length + si.filesize]; Buffer.BlockCopy(header, 0, total, 0, header.Length); Buffer.BlockCopy(infobuffer, 0, total, header.Length, infobuffer.Length); // Если ΠΏΡƒΡ‚ΡŒ Ρ„Π°ΠΉΠ»Π° ΡƒΠΊΠ°Π·Π°Π½, Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π΅Π³ΠΎ содСрТимоС Π² отправляСмый массив Π±Π°ΠΉΡ‚ΠΎΠ² if (si.filesize > 0) { FileStream fs = new FileStream(SendFileName, FileMode.Open, FileAccess.Read); fs.Read(total, header.Length + infobuffer.Length, si.filesize); fs.Close(); fs = null; } try { // ΠžΡ‚ΠΏΡ€Π°Π²ΠΈΠΌ Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Π½Ρ‹ΠΌ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°ΠΌ NetworkStream ns = _tcpClient.tcpClient.GetStream(); // Π’Π°ΠΊ ΠΊΠ°ΠΊ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄ вызываСтся Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ΅ Ρ€Π°Ρ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Π΅ΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ синхронный ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ns.Write(total, 0, total.Length); // ΠžΠ±Π½ΡƒΠ»ΠΈΠΌ всС ссылки Π½Π° ΠΌΠ½ΠΎΠ³ΠΎΠ±Π°ΠΉΡ‚Π½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΈ ΠΏΠΎΠΏΡ€ΠΎΠ±ΡƒΠ΅ΠΌ ΠΎΡ‡ΠΈΡΡ‚ΠΈΡ‚ΡŒ ΠΏΠ°ΠΌΡΡ‚ΡŒ header = null; infobuffer = null; total = null; SendFileName = null; GC.Collect(); GC.WaitForPendingFinalizers(); // ΠŸΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎΠΉ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ Parent.ShowReceiveMessage("Π”Π°Π½Π½Ρ‹Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ ΠΎΡ‚ΠΏΡ€Π°Π²Π»Π΅Π½Ρ‹!"); } catch(Exception ex) { MessageBox.Show(ex.ToString()); } } 

Here is the function of accepting the file on the Client side:

 public void ReadCallback(IAsyncResult ar) { if (modeNetwork == Mode.indeterminately) return; TcpClientData myTcpClient = (TcpClientData)ar.AsyncState; try { NetworkStream ns = myTcpClient.tcpClient.GetStream(); int r = ns.EndRead(ar); if (r > 0) { // Из Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ массива Π±Π°ΠΉΡ‚ΠΎΠ² ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° string header = Encoding.Default.GetString(myTcpClient.buffer); int leninfo = int.Parse(header); // ΠŸΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΠΈ дСсСриализуСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠ΅ΠΉ ΠΎ содСрТании ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌΠΎΠ³ΠΎ сСтСвого ΠΏΠ°ΠΊΠ΅Ρ‚Π° MemoryStream ms = new MemoryStream(leninfo); byte[] temp = new byte[leninfo]; r = ns.Read(temp, 0, temp.Length); ms.Write(temp, 0, r); BinaryFormatter bf = new BinaryFormatter(); ms.Position = 0; SendInfo sc = (SendInfo)bf.Deserialize(ms); ms.Close(); if (sc.filesize > 0) { // Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ Ρ„Π°ΠΉΠ» Π½Π° основС ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠΉ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΈ массива Π±Π°ΠΉΡ‚ΠΎΠ² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π·Π° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ FileStream fs = new FileStream(sc.filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, sc.filesize); do { temp = new byte[global.MAXBUFFER]; r = ns.Read(temp, 0, temp.Length); // ЗаписываСм строго ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Π±Π°ΠΉΡ‚ΠΎΠ² сколько ΠΏΡ€ΠΎΡ‡Ρ‚Π΅Π½ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ Read() fs.Write(temp, 0, r); // Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Ρ‹ всС Π±Π°ΠΉΡ‚Ρ‹ Ρ„Π°ΠΉΠ»Π°, останавливаСм Ρ†ΠΈΠΊΠ», // ΠΈΠ½Π°Ρ‡Π΅ ΠΎΠ½ заблокируСтся Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ Π½ΠΎΠ²Ρ‹Ρ… сСтСвых Π΄Π°Π½Π½Ρ‹Ρ… if (fs.Length == sc.filesize) { fs.Close(); fs = null; break; } } while (r > 0); temp = null; GC.Collect(); GC.WaitForPendingFinalizers(); } if (Receive != null) Receive(this, new ReceiveEventArgs(sc)); myTcpClient.buffer = new byte[global.LENGTHHEADER]; ns.BeginRead(myTcpClient.buffer, 0, myTcpClient.buffer.Length, new AsyncCallback(ReadCallback), myTcpClient); } else { DeleteClient(myTcpClient); // Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΡΡ if (Disconnected != null) Disconnected.BeginInvoke(this, "ΠšΠ»ΠΈΠ΅Π½Ρ‚ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΡΡ!", null, null); } } catch (Exception e) { MessageBox.Show(e.ToString()); DeleteClient(myTcpClient); // Π‘ΠΎΠ±Ρ‹Ρ‚ΠΈΠ΅ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ ΠΎΡ‚ΠΊΠ»ΡŽΡ‡ΠΈΠ»ΡΡ if (Disconnected != null) { Disconnected.BeginInvoke(this, "ΠŸΡ€ΠΎΠΈΠ·ΠΎΡˆΠ»Π° ошибка Π²ΠΎ врСмя обновлСния Π‘Π°Π·Ρ‹ Π”Π°Π½Ρ‹Ρ…. ΠŸΡ€ΠΎΡΡŒΠ±Π° ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΈΡ‚ΡŒ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΡƒ.", null, null); } SoundError(); } } 

This is the class that exists both on the Client and on the Server:

 [Serializable] class SendInfo { public string message; public string filename; public int filesize; } 

Here on this line

 SendInfo sc = (SendInfo)bf.Deserialize(ms); 

and an error occurs, namely, writes:

{"Failed to cast object type \" SERVER.SendInfo \ "to type \" KLIENT.SendInfo \ "."} System.Exception {System.InvalidCastException}

  • And what you do not understand from the text of the error? - Andrew NOP
  • Unclear? And the fact that the class is the same, that in the Client, that in the Server. And he can not bring. As it is not normal in my opinion. I think there are not enough lines in the settings - Ignat
  • On the server you have a class SERVER.SendInfo and on the client KLIENT.SendInfo . These are different classes, even if their definitions are the same. - PetSerAl
  • Does it matter for serialization? She would have classes that were the same name, and the field. Please tell me what to do, the third day I am breaking my head. - Ignat
  • She would have classes that were the same name, and the field. And you can link to the documentation, where did you read it? Please tell me what to do, the third day I am breaking my head. Remove one of the classes. PS If you divide the string SendInfo sc = (SendInfo)bf.Deserialize(ms); on object o = bf.Deserialize(ms); and SendInfo sc = (SendInfo)o; , then you will see that the exception does not appear in the call to Deserialize . - PetSerAl

1 answer 1

You can see from the error that you are trying to cast an object of one type to an object of another type. Even if the classes have the same fields and the same name, they are still different classes.

There are two possible solutions to the problem:

  • implement an explicit statement;
  • rendered the serializable class in a separate assembly (class library) and connect it for both projects.

Related Links: