Я создаю игру, которая требует большого трафика данных, таких как Positions (2D) и многих других данных.Я использую очень простой класс, чтобы помочь мне прослушивать порт 8080 (UDP), и метод для отправки дейтаграммы:
public static void SendToHostUDP(string Msg)
{
UdpClient udpClient = new UdpClient();
udpClient.Connect(Main.HostIP, 8080);
byte[] sdBytes = Encoding.ASCII.GetBytes(Msg);
udpClient.BeginSend(sdBytes, sdBytes.Length, CallBack, udpClient);
Main.UDPout += sdBytes.Length / 1000f;
}
public static void SendToClientUDP(string Msg, IPAddress ip)
{
UdpClient udpClient = new UdpClient();
udpClient.Connect(ip, 8080);
byte[] sdBytes = Encoding.ASCII.GetBytes(Msg);
udpClient.BeginSend(sdBytes, sdBytes.Length, CallBack, udpClient);
Main.UDPout += sdBytes.Length / 1000f;
}
public static void CallBack(IAsyncResult ar)
{
}
Класс слушателя очень простой:
public class NetReciever
{
public TcpListener tcpListener;
public Thread listenThread;
private Action actionToPerformTCP;
private Action actionToPerformUDP;
public UdpClient udpClient;
public Thread UDPThread;
TimerAction UDPPacketsCounter;
int UDPPacketsCounts;
private BackgroundWorker bkgUDPListener;
string msg;
public NetReciever(IPAddress IP)
{
this.tcpListener = new TcpListener(IPAddress.Any, 25565);
this.udpClient = new UdpClient(8080);
this.UDPThread = new Thread(new ThreadStart(UDPListen));
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
UDPPacketsCounter = new TimerAction(CountUDPPackets, 1000, false);
this.UDPThread.Start();
}
public void CountUDPPackets()
{
UDPPacketsCounts = 0;
}
public void Abort()
{
UDPThread.Abort();
udpClient.Close();
listenThread.Abort();
tcpListener.Stop();
}
public void UDPListen()
{
while (true)
{
IPEndPoint RemoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0);
byte[] receiveBytesUDP = udpClient.Receive(ref RemoteIPEndPoint);
if (receiveBytesUDP != null)
{
UDPPacketsCounts++;
Main.UDPin += receiveBytesUDP.Length / 1000f;
}
if (Main.isHost)
{
Main.Server.processUDP(Encoding.ASCII.GetString(receiveBytesUDP), RemoteIPEndPoint.Address.ToString());
}
else
{
if (RemoteIPEndPoint.Address.ToString() == Main.HostIP)
{
Program.game.ProcessUDP(Encoding.ASCII.GetString(receiveBytesUDP));
}
}
}
}
Таким образом, в основном, когда есть 1 игрок, будет приблизительно 60 пакетов / с IN и 60 пакетов / с.
Это действует так:
- Прослушивание пакетов.
- Проверка пакетов.
- Обработка данных пакетов -> Как сохранение некоторых позиций, отправление некоторых пакетов ...
Так что это просто циклthis.
И проблемы здесь:
Во-первых, когда будет 2 игрока (Host + 1Client), в какой-то момент произойдет несколько значительных падений FPS, и хост будет испытывать заиканиевсе аудио (как на синем экране) на мгновение.
Во-вторых, когда есть 2+ игрока (Host + 1 + Client), FPS хоста упадет до 5-20, и будет отставать + отставать+ лаг + лаг, но не замораживание.
Я прочитал несколько статей об асинхронности, и это ужеAdy Threadded?
А также BeginRecieve
и EndRecieve
, я не очень понимаю, как и зачем мне это нужно использовать.
Может кто-то любезно предоставить несколько примеров, чтобы объяснить, какобрабатывать эти виды данных и отправлять / получать пакеты, пожалуйста?Я действительно не хочу использовать библиотеки, потому что я хочу знать, что происходит.
PS: Как работает сетевая система в Terraria?Он использует TCP, но это гладко!Как?
PSS: Что такое буферизация?Зачем мне устанавливать буферизацию и как?Что это меняет?
PSSS: Я думаю, что есть что-то, что нужно настроить и изменить при отправке пакетов, потому что это выглядит просто.