c#对象不更新

时间:2012-06-27 06:57:10

标签: c# object serialization reference deserialization

我正在尝试运行原始游戏服务器。到目前为止,我已到达这一点(注释行),服务器运行顺畅。但是,如果我再次从客户端发送对象,它不会多次更新。 因此,例如,客户端使用新位置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;
                    }
                }
            }
        }
}

2 个答案:

答案 0 :(得分: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;
                }
            }
        }
    }

答案 1 :(得分:1)

美好的一天user1181369,

我之前没有使用过MemoryStream,但是我一直在通过MSDN库进行一些研究,我怀疑'ms'没有清除,你加载的所有数据实际上都被添加到流中而不是替换它。

例如,MemorySteam.Flush()实际上并没有做任何事情(http://msdn.microsoft.com/en-us/library/system.io.memorystream.flush.aspx)。如果是这种情况,那么for循环会在找到特定玩家ID的第一个实例时中断,而不是找到更新的版本。

另外,我不确定你提供的代码会如何反序列化多个玩家,但这超出了这个问题的范围,也可能超出了我目前的知识领域。

令人遗憾的是,虽然我认为我可能已经诊断出了这个问题,但我现在还没有能力提供解决方案,除了在每个循环中实例化一个新的内存流之外。