2

こんにちは、私はチャット プログラムを作成しています。メインのチャット ウィンドウのメッセージ、現在チャットしている人のリスト、プライベートのいずれかを含む、さまざまな種類のパケットを送信するための一連の子クラスを持つ親「MessagePacket」クラスがあります。チャットメッセージなど

クライアントで最初に行うことは、「AddClientPacket」を作成し、それをシリアル化/サーバーに送信することです。サーバーは、キャスト/実行するものを決定するために使用される型プロパティを含む親「MessagePacket」クラスとしてそれを逆シリアル化します取得した汎用 MessagePacket を使用します。

サーバーがそれを逆シリアル化しようとすると、クラッシュが発生しますが、その理由はわかりません。いくつかのコードを次に示します。

- サーバ -

    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;
            }
        }
    }

- クライアント -

    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;
            }
        }
    }
4

1 に答える 1

1

それならそれが問題だろう。それらは同じように「見え」、同じプロパティを持っていますが、2 つの異なるアセンブリで定義されている場合、.NET はそれらを完全に異なる型と見なすため、TypeA をシリアル化して TypeB に逆シリアル化することはできません。両方が共有するクラス定義を使用して、単一の .dll を作成する必要があります。

于 2012-10-09T02:23:30.237 に答える