【发布时间】:2014-11-23 19:08:10
【问题描述】:
我有这个学校项目,我正在使用 TCPClient-Server 在 LAN 上制作回合制 RPG。到目前为止,我已经能够通过序列化和反序列化对象将他们选择的类从两个客户端发送到服务器,但是现在我无法将播放器 2 角色发送到播放器 1 客户端(播放器 1 充当主机,并且服务器程序在该计算机上运行)。
客户代码
//part where I send the character to the server
byte[] player;
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, Player);
player = ms.ToArray();
byte[] DLen = BitConverter.GetBytes((Int32)player.Length);
netstream = Cliente.GetStream();
netstream.Write(DLen, 0, 4);
netstream.Write(player, 0, player.Length);
netstream.Flush();
ms.Flush();
//part where I receive the other client's character from the server
byte[] DataLength = new byte[4];
netstream = Cliente.GetStream();
netstream.Read(DataLength, 0, 4);//<----HOST Client "skips" this line (executes instruction BEFORE Reset Event was notified in server side)
int length = BitConverter.ToInt32(DataLength, 0);
player = new byte[length];
netstream.Read(player, 0, length);
ms = new MemoryStream(player);
bf = new BinaryFormatter();
ms.Position = 0;
object ob = bf.Deserialize(ms);//<----Line where exception appears ONLY on HOST Client
CPU = (ACharacter)ob;
netstream.Flush();
服务器代码
AutoResetEv.WaitOne();//<---Waits until BOTH players have selected their characters
//Begin sending to P2
byte[] player;
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, Player1);
player = ms.ToArray();
byte[] DataLength = BitConverter.GetBytes((Int32)player.Length);
netstream = Jug2Sock.GetStream();
netstream.Write(DataLength, 0, 4);
netstream.Write(player, 0, player.Length);
netstream.Flush();
//Finished sending to P2
//Begin sending to P1
ms = new MemoryStream();
bf = new BinaryFormatter();
bf.Serialize(ms, Player2);
player = ms.ToArray();
DataLength = BitConverter.GetBytes((Int32)player.Length);
netstream = Jug1Sock.GetStream();
netstream.Write(DataLength, 0, 4);
netstream.Write(player, 0, player.Length);
netstream.Flush();
//Finished sending to P1
我真的不知道这里有什么问题,因为玩家 1 的角色使用相同的代码正确发送到玩家 2,但是我注意到由于某种原因,在 P1 的客户端中,读取数据长度的行被“跳过” ”。我的意思是说客户端 1 只是在服务器发送数据之前执行指令(服务器被 AutoResetEvent 搁置以控制它)。
非常感谢您的帮助。
【问题讨论】:
-
netstream.Read(player, 0, length);你必须在这里检查实际读取了多少字节。比如int bytesRead = netstream.Read(player, 0, length);不保证是4。 -
这就是我正在做的,首先我发送我要读取的数据的大小:netstream.Read(DataLength, 0, 4);我先发送该数据,我知道它是 4 个字节,因为它是这样指定的,然后我使用长度来反序列化另一部分,事情似乎是由于某种原因数据没有正确发送
-
问题是
netstream.Read(...)。如果您编码:int y = netstream.Read(DataLength, 0, x);,则 y 可以是 0 到 x 之间的任何数字。这就是您需要处理的重点。 -
有趣的是,只有主机客户端的数据不正确,所以我认为问题可能是其他的,正如我之前所说,客户端 1“跳过”读取行,而不是从字面上看,它做到了,但它是应该在客户端 2 选择一个字符之后才执行的行,但它会在它发生之前执行该行,但是如果客户端 2 在客户端 1 之前做出选择,客户端 2 不会得到异常,但客户端 1 还是得到了它
标签: c# networking serialization stream deserialization