我正在開發一個項目,該項目利用簡單的Socket連接在Packet.cs對象之間傳遞客戶端和服務器之間的小型變量作爲「旅行模式」。客戶端和服務器是不同項目的一部分,但是同樣的解決方案,Packet.cs也是一個單獨的「共享項目」。解碼消息時的反序列化異常
這是我packet.cs文件:
using System;
using System.Net;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading.Tasks;
using System.Collections.Generic;
namespace ConnectionData
{
[Serializable]
public class Packet
{
// these are all the different types of things we can send
public List<string> gData;
public string packetString;
public int packetInt;
public bool packetBool;
public PacketType packetType;
// senderID is going to be the unique GUID that we generated
public string senderID;
public Packet (PacketType type, string senderID)
{
gData = new List<String>();
this.senderID = senderID;
this.packetType = type;
}
public Packet(byte[] packetBytes)
{
// deconstructs the bytes we received into packet form
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream (packetBytes);
Packet p = (Packet)bf.Deserialize (ms);
ms.Close();
// assigns all the values from the packet info we received in byte form
this.gData = p.gData;
this.packetInt = p.packetInt;
this.packetBool = p.packetBool;
this.senderID = p.senderID;
this.packetType = p.packetType;
}
// this converts the whole packet object into a byte array to send through the socket
public byte[] ToBytes()
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize (ms, this);
byte[] bytes = ms.ToArray();
ms.Close();
return bytes;
}
// this function will return the active IP address of the system. if it
// cant find one, it returns default local address
public static string GetIP4Address()
{
// this lists all addresses shown in IPConfig
IPAddress[] ips = Dns.GetHostAddresses (Dns.GetHostName());
foreach(IPAddress i in ips)
{
// if there's an IP4 address in the list, return it
if (i.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return i.ToString();
}
}
// else return local address
return "127.0.0.1";
}
// enum makes it so we can define different strings, makes the packetType really easy to work with
// allows us to define what kind of packet it is
public enum PacketType
{
Registration, CloseConnection, Command
}
}
}
這是我用什麼來發送數據。當我在服務器上創建的消息發送到客戶端,我只需撥打Packet p = new Packet(Packet.PacketType.Command);
和socket.Send(p.ToBytes());
接收的數據包(兩個項目)用途:
public void Data_IN (object cSocket)
{
Socket clientSocket = (Socket)cSocket;
byte[] buffer;
int readBytes;
while (Server.listening) {
// sets our buffer array to the max size we're able to receive
buffer = new byte[clientSocket.SendBufferSize];
// gets the amount of bytes we've received
readBytes = clientSocket.Receive (buffer);
// if we actually recieve something, then sort through it
if (readBytes > 0) {
// handle data
Packet packet = new Packet (buffer);
DataManager (packet); // handles the packet data
}
}
}
產生的問題是,當我嘗試發送在第一個連接上註冊數據包。我啓動我的服務器項目,讓它執行等待,一切正常。客戶端是能夠連接和服務器發送其在這裏創建了註冊分組:
Packet p = new Packet (Packet.PacketType.Registration, Server.guid);
p.packetString = HeartCore.commandKey; // commandKey is a static string variable
clientSocket.Send (p.ToBytes());
服務器表明它已經成功發送,然後客戶端會拋出異常。好極了!客戶端處理收到的數據包,如上圖所示Data_IN
。它創建於
if (readBytes > 0) {
// handle data
Packet packet = new Packet (buffer); // this is where it stops
DataManager (packet); // handles the packet data
}
和
public Packet(byte[] packetBytes)
{
// deconstructs the bytes we received into packet form
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream (packetBytes);
Packet p = (Packet)bf.Deserialize (ms); //EXCEPTION OCCURS HERE
ms.Close();
...
新的數據包後,如果你還記得,包類有一個構造函數中的字節[]緩衝區,並將其轉換成一個對象,則會出現異常的權利,然後將臨時數據包對象中的值複製到正在使用的實際對象。
所引發的異常是
System.Runtime.Serialization.SerializationException: Couldn't find assembly 'Heart' ---> System.Exception: Could not load file or assembly 'Heart' or one of its dependencies. The system cannot find the file specified.
at System.AppDomain.Load (System.String assemblyString, System.Security.Policy.Evidence assemblySecurity, Boolean refonly) [0x00000] in <filename unknown>:0
at System.AppDomain.Load (System.String assemblyString) [0x00000] in <filename unknown>:0
at at (wrapper remoting-invoke-with-check) System.AppDomain:Load (string)
at System.Reflection.Assembly.Load (System.String assemblyString) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetDeserializationType (Int64 assemblyId, System.String className, Boolean throwOnError) [0x00000] in <filename unknown>:0
--- End of inner exception stack trace ---
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetDeserializationType (Int64 assemblyId, System.String className, Boolean throwOnError) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetDeserializationType (Int64 assemblyId, System.String className) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadTypeMetadata (System.IO.BinaryReader reader, Boolean isRuntimeObject, Boolean hasTypeInfo) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectInstance (System.IO.BinaryReader reader, Boolean isRuntimeObject, Boolean hasTypeInfo, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObject (BinaryElement element, System.IO.BinaryReader reader, System.Int64& objectId, System.Object& value, System.Runtime.Serialization.SerializationInfo& info) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadNextObject (BinaryElement element, System.IO.BinaryReader reader) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.ReadObjectGraph (BinaryElement elem, System.IO.BinaryReader reader, Boolean readHeaders, System.Object& result, System.Runtime.Remoting.Messaging.Header[]& headers) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.NoCheckDeserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) [0x00000] in <filename unknown>:0
at ConnectionData.Packet..ctor (System.Byte[] packetBytes) [0x00016] in /home/austin/Programming/C#/Crystal-Home-Systems/ConnectionData/Packet.cs:63
at Shard.Client.Data_IN() [0x0002f] in /home/austin/Programming/C#/Crystal-Home-Systems/Shard/Client.cs:90
at System.Threading.Thread.StartInternal() [0x00000] in <filename unknown>:0
現在,我是半新的C#語言本身,但我有與Java經驗像樣的數目,也做了這種類型的服務器 - 客戶端的工作與之前。我花了大約5個小時左右的時間改變事情,使用谷歌,甚至要求幾個編程的朋友,我們一直無法弄清楚發生了什麼。 Couldn't find assembly 'Heart'
引用我對項目Heart的看法,它是發送導致崩潰的數據包的服務器類。
有沒有人有任何想法可能會導致崩潰?我越來越惱火,覺得我失去了超級明顯的東西。我試圖儘可能具體,請讓我知道,如果我忘記了任何問題或如果你需要更多的細節!
非常感謝您的幫助!
編輯:只是爲了澄清,服務器和客戶端都能夠連接沒有問題,嘗試解碼由服務器發送到客戶端的註冊數據包時發生錯誤。另外,它可以在使用mono的Linux系統Kubuntu上運行。我不認爲會有所作爲,但它可能
*'我試過各種各樣的東西,包括CodeCaster給出的驚人答案,但是沒有任何工作。「*,你沒有嘗試他的答案,因爲他的答案的第一句話是告訴你做什麼,你完成了」沒有任何工作後產生「 –
我不是真的確定你在哪裏獲得,解決方案是我爲Packet.cs創建SharedProject的方式。我無法使用SharedProject,我需要一個SharedLibrary。如果這就是他的回答所說的話,我會接受它,但是據我所知它不是。 – PulsePanda