1

プリミティブ ゲーム サーバーを実行しようとしています。これまでのところ、この時点 (コメント行) に到達し、サーバーはスムーズに実行されます。しかし、クライアントからオブジェクトを再度送信すると、複数回更新されません。たとえば、クライアントはシリアル化されたプレーヤー オブジェクトを新しい位置 Vector2(400,50) で送信しますが、サーバーはそれを古い位置を取得したオブジェクトに逆シリアル化します。


プレイヤーコード

namespace Commons.Game
{
    [Serializable]
    public class Unit
    {
        #region Fields
        public int ID;
        public Vector2 position;
        public string name;
        public int HP;
        public int XP;
        public int Lvl;
        public bool active;
        public float speed;
        public string password;
        #endregion

        public Unit(Vector2 position, int HP, float speed, string name, string password, int ID)
        {
            active = true;
            this.position = position;
            this.HP = HP;
            this.XP = 0;
            this.speed = speed;
            this.name = name;
            this.Lvl = 1;
            this.password = password;
            this.ID = ID;
        }


サーバーコード

namespace SocketServer.Connection
{
    class Server
    {
        #region Fields
        Unit[] players;

        UdpClient playersData;

        Thread INHandlePlayers;

        BinaryFormatter bf;

        IPEndPoint playersEP;

        #endregion

        public Server()
        {
            this.players = new Unit[5];

            bf = new BinaryFormatter();

            this.playersData = new UdpClient(new IPEndPoint(IPAddress.Any, 3001));
            this.playersEP = new IPEndPoint(IPAddress.Any, 3001);

            this.INHandlePlayers = new Thread(new ThreadStart(HandleIncomePlayers));
            this.INHandlePlayers.Name = "Handle income players.";

            this.INHandlePlayers.Start();
        }

        private void HandleIncomePlayers()
        {
            Console.Out.WriteLine("Players income handler started.");
            MemoryStream ms = new MemoryStream();

            while (true)
            {
                byte[] data = playersData.Receive(ref playersEP);
                ms.Write(data, 0, data.Length); 
                ms.Position = 0;
                Unit player = null; 
                player = bf.Deserialize(ms) as Unit; //<-- 1st deserialization is OK, bu  after another client update, object doesn't change. So I change Vector with position at client, that sends correct position I want, but at server side position doesn't change after first deserialization.
                Console.Out.WriteLine(player.name + " " + player.position.X + " " + player.position.Y);
                ms.Flush();
                for (int i = 0; i < players.Length; i++)
                {
                    if (players[i] != null && player.ID == players[i].ID)
                    {
                        players[i] = player;
                        break;
                    }
                }
            }
        }
}
4

2 に答える 2

2

おい、それについてはよくわかりませんが、以下のように、ループ内で MemoryStream オブジェクトをインスタンス化します。

このコードを正しく試すことはできません。申し訳ありません。

    private void HandleIncomePlayers()
    {
        Console.Out.WriteLine("Players income handler started.");
        MemoryStream ms;

        while (true)
        {
            ms = new MemoryStream(); //here
            byte[] data = playersData.Receive(ref playersEP);
            ms.Write(data, 0, data.Length); 
            ms.Position = 0;
            Unit player = null; 
            player = bf.Deserialize(ms) as Unit;

            Console.Out.WriteLine(player.name + " " + player.position.X + " " + player.position.Y);
            ms.Dispose(); //and here
            for (int i = 0; i < players.Length; i++)
            {
                if (players[i] != null && player.ID == players[i].ID)
                {
                    players[i] = player;
                    break;
                }
            }
        }
    }
于 2012-06-27T07:21:08.570 に答える
1

こんにちは user1181369,

私は以前に MemoryStream を使用したことはありませんが、MSDN ライブラリを少し調べてみたところ、「ms」がクリアされておらず、読み込んだすべてのデータが実際にストリームに追加されているのではないかと疑っています。それを交換します。

たとえば、MemorySteam.Flush() は実際には何もしません ( http://msdn.microsoft.com/en-us/library/system.io.memorystream.flush.aspx )。この場合、特定のプレーヤー ID の最初のインスタンスが見つかった時点で for ループが壊れ、新しいバージョンは見つかりません。

また、あなたが提供したコードが複数のプレーヤーをどのように逆シリアル化するかはわかりませんが、それはこの質問の範囲外であり、おそらく私の現在の知識の範囲を超えています.

残念ながら、問題を診断できたと思いますが、現時点では、各ループで新しいメモリストリームをインスタンス化する以外の解決策を提供する準備ができていません。

于 2012-06-27T07:15:15.480 に答える