2012-10-07 91 views
2

嘿傢伙我正在做一個聊天程序,我有一個父類「MessagePacket」類與一堆兒童類爲不同類型的數據包發送,包含主聊天窗口的消息,私人聊天消息等網絡流二進制序列化

在客戶端中,我所做的第一件事是創建一個「AddClientPacket」並將其序列化/發送給服務器,然後服務器將其反序列化爲其父「MessagePacket」它包含一個類型屬性,該屬性用於確定使用通用MessagePacket進行投射/做什麼。

當服務器試圖反序列化它會導致崩潰,我不知道爲什麼。下面有一些代碼:

--SERVER--

private void HandleClientComm(Object client) 
    { 
     Client addClient = new Client(clientIds++, ((TcpClient)client).GetStream()); 

     IFormatter formatter = new BinaryFormatter(); 


     while (true) 
     { 
      MessagePacket packet = new MessagePacket(); 

      try 
      { 
       packet = (MessagePacket)formatter.Deserialize(addClient.ClientStream); 
      } 
      catch (Exception e) 
      { 
       MessageBox.Show(e.Message); 
      } 



      switch (packet.Type) 
      { 
       case MessageType.ALLCHAT: 
        { 
         messages.Enqueue(((AllChatPacket)packet).Message); 
        } 
       break; 
       case MessageType.ADDCLIENT: 
        { 

         addClient.ClientName = ((AddClientPacket)packet).ClientName; 
         clientNames.Add(addClient.ClientName); 
         clientList.Add(addClient); 
        } 
       break; 
       case MessageType.REMOVECLIENT: 
        { 
         clientNames.Remove(addClient.ClientName); 
         clientList.Remove(addClient); 
        } 
        break; 
       case MessageType.PRIVATECHAT: 
        { 

        } 
        break; 
      } 
     } 
    } 

--CLIENT--

public void ListenToServer() 
    { 
     AddClientPacket addClient = new AddClientPacket(); 
     addClient.Type = MessageType.ADDCLIENT; 


     name = addClient.ClientName = Interaction.InputBox("Whats your name", "Name?", "", 100, 100); 

     try 
     { 
      formatter.Serialize(clientStream, addClient); 
     } 
     catch (Exception e) 
     { 
      MessageBox.Show(e.Message); 
      this.Close(); 
      return; 
     } 


     while (true) 
     { 
      if (quit) 
      { 
       break; 
      } 

      MessagePacket packet = new MessagePacket(); 

      try 
      { 
       packet = (MessagePacket)formatter.Deserialize(clientStream); 
      } 
      catch (Exception) 
      { 
       return; 
      } 

      switch (packet.Type) 
      { 
       case MessageType.ALLCHAT: 
        { 
         textBox1.Text = textBox1.Text + Environment.NewLine + ((AllChatPacket)packet).Message; 
         textBox1.Refresh(); 
        } 
        break; 
       case MessageType.NAMELIST: 
        { 
         clientNameList.DataSource = ((NameListPacket)packet).ClientNames; 
        } 
        break; 
      } 
     } 
    } 
+0

沒有引發異常?事件日誌中有關於崩潰的任何內容?您可以嘗試將AppDomain.Current.UnhandledExceptions + =(a,b)=> File.WriteAllText(「errorlog.txt」,b.ExceptionObject)捕獲上次引發的錯誤。您可以嘗試創建您正在序列化的數據包的原始字節的哈希,然後在服務器上直接讀取TcpClient流,然後對其進行哈希以確保哈希值相同。這將確保數據正確傳輸。 – Despertar

+0

是的抱歉引發異常,並且消息是: 「無法找到程序集'ChatClient,版本1.0.0.0,文化=中立,PublicKeyToken = null' 儘管ChatServer是試圖Deserualize來自ChatClient的消息 – ThingWings

+1

正確的,ChatClient.dll和ChatServer.exe在同一目錄下也是如此?如果你有一個客戶端和服務器需要使用的自定義數據包類型,通常你會把它抽象成它自己的程序集(.dll ),所以它可以被兩者共享 – Despertar

回答

1

這將是問題,那麼。即使他們對你來說看起來是一樣的,但它們具有相同的屬性,如果它們被定義在兩個不同的程序集中,.NET將它們視爲完全不同的類型,因此不會讓您將TypeA序列化並將其反序列化爲TypeB。您將不得不創建一個具有該類共享的類定義的.dll。