所以我的问题是我的服务器无法接收客户端发送的所有数据,这导致服务器端几乎没有收到任何数据包。
基本上问题是我需要大量睡眠 CLientLoop ,以便接收发送的数据。如 Thread.Sleep(1000)
(这是在本地测试过的)
我的服务器代码在这里:
public void RecieveAsync()
{
socket.BeginReceive(lenBuffer, 0, lenBuffer.Length, SocketFlags.None,recieveCallBack, null);
}
private void recieveCallBack(IAsyncResult ar)
{
int rec = socket.EndReceive(ar);
if (rec == 0)
{
if (Disconnected != null)
{
Disconnected(this);
return;
}
if (rec != 4)
{
throw new Exception();
}
}
/
buffer = new ReceiveBuffer(BitConverter.ToInt32(lenBuffer, 0));
也是我为那些感兴趣的人准备的缓冲类(可能有帮助)
\ public struct ReceiveBuffer { public const int BUFFER_SIZE = 1024; 公共字节[]缓冲区;公共 int 接收;公共 MemoryStream BufStream;
public ReceiveBuffer(int toRec)
{
Buffer = new byte[BUFFER_SIZE];
ToReceive = toRec;
BufStream = new MemoryStream(toRec);
}
public void Dispose()
{
Buffer = null;
ToReceive = 0;
Close();
if (BufStream != null) BufStream.Dispose();
}
public void Close()
{
if (BufStream != null && BufStream.CanWrite)
{
BufStream.Close();
}
}
所以我的客户正在用这种方法发送数据
public void Send(byte[] data, int index, int length)
{
//add data as state
socket.BeginSend(BitConverter.GetBytes(length), 0, 4, SocketFlags.None, new AsyncCallback(sendCallback), data);
socket.BeginSend(data, index, length, SocketFlags.None, new AsyncCallback(sendCallback), null);
}
发送信息的位置在这里
public void ClientLoop()
{
try{
Console.WriteLine("In Client loop");
client.DataRecieved +=new Client.DataRecievedEventHandler(Client_DataRecieved);
while (true)
{
byte[] playerData = PreparePlayerData();
client.Send(playerData, 0, playerData.Length);
//client.RecieveAsync();
Thread.Sleep(10);
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
}
和
public byte[] PreparePlayerData()
{
BinaryWriter bw = new BinaryWriter(new MemoryStream());
bw.Write((int)Commands.Text);
string data = "";
string Position = Math.Round(MultiplayerScreen.localPlayer.Position.X, 2).ToString() + "|" + Math.Round(MultiplayerScreen.localPlayer.Position.Y, 2).ToString();
string effects = (MultiplayerScreen.localPlayer.Effects == Microsoft.Xna.Framework.Graphics.SpriteEffects.None) ? "0" : "1";
string animaton = (MultiplayerScreen.localPlayer.Animation.MoveState).ToString();
string frame = MultiplayerScreen.localPlayer.Animation.XFrame.ToString();
data = "P|" + Position + "|" + effects + "|" + animaton + "|" + frame;
bw.Write(data);
bw.Close();
byte[] toSend = ((MemoryStream)bw.BaseStream).ToArray();
bw.BaseStream.Dispose();
return toSend;
}
这也是服务器处理接收到的数据的方法
void Client_DataRecieved(Client sender, ReceiveBuffer e)
{
BinaryReader r = new BinaryReader(e.BufStream);
Commands header = (Commands)r.ReadInt32();
string s = r.ReadString();
Console.WriteLine("Client has received " + s);
switch (header)
{
case Commands.Player:
{
HandlePlayerData(s);
Console.WriteLine("The player data has been updated");
}
break;
case Commands.Text:
{
if (s.StartsWith("clientAccepted"))
{
connectedPlayer.isOnline = true;
}
if (s.StartsWith("P|"))
{
s = s.Remove(0, 2);
HandlePlayerData(s);
}
}
break;
}
}
socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallback, null);
}
void receivePacketCallback(IAsyncResult ar)
{
int rec = socket.EndReceive(ar);
if (rec <= 0)
{
return;
}
buffer.BufStream.Write(buffer.Buffer, 0, rec);
buffer.ToReceive -= rec;
if (buffer.ToReceive > 0)
{
Array.Clear(buffer.Buffer, 0, buffer.Buffer.Length);
socket.BeginReceive(buffer.Buffer, 0, buffer.Buffer.Length, SocketFlags.None, receivePacketCallback, null);
return;
}
if (DataRecieved != null)
{
buffer.BufStream.Position = 0;
DataRecieved(this, buffer);
}
buffer.Dispose();
}