我正在尝试运行原始游戏服务器。到目前为止,我已到达这一点(注释行),服务器运行顺畅。但是,如果我再次从客户端发送对象,它不会多次更新。 因此,例如,客户端使用新位置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;
}
}
}
}
}
答案 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的第一个实例时中断,而不是找到更新的版本。另外,我不确定你提供的代码会如何反序列化多个玩家,但这超出了这个问题的范围,也可能超出了我目前的知识领域。
令人遗憾的是,虽然我认为我可能已经诊断出了这个问题,但我现在还没有能力提供解决方案,除了在每个循环中实例化一个新的内存流之外。