したがって、私の問題は、クライアントが送信しているすべてのデータをサーバーが受信できないことです。これにより、サーバー側でパケットがまったく受信されなくなります。
基本的に問題は、送信されたデータを受信するために、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; publicbyte[]バッファ; public int ToReceive; public 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();
}