我正在开展这个学校项目,我正在使用TCPClient-Server在LAN上制作基于回合制的RPG。到目前为止,我已经能够通过序列化和反序列化对象将两个客户端的选定类发送到服务器,但现在我无法将Player 2字符发送到Player 1客户端(Player 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保留以便控制它)。
非常感谢你的帮助。
答案 0 :(得分:2)
我认为您需要处理Read操作返回的读取字节数
netstream = Cliente.GetStream();
int numBytesToRead = 4;
do
{
// Read may return anything from 0 to 4.
int n = netstream.Read(DataLength, numBytesRead, numBytesToRead);
numBytesRead += n;
numBytesToRead -= n;
} while (numBytesToRead > 0);
int length = BitConverter.ToInt32(DataLength, 0);
这是如何处理前4个字节(包含DataLength)的读取示例。阅读球员数据可以这样做:
player = new byte[length];
numBytesRead = 0;
numBytesToRead = length;
do
{
int n = netstream.Read(player, numBytesRead, numBytesToRead);
numBytesRead += n;
numBytesToRead -= n;
} while (numBytesToRead > 0);
ms = new MemoryStream(player);