我正在製作一個遊戲,要求位置(2D)和許多其他數據的數據流量很大。 我用一個很簡單的類來幫助我監聽8080端口(UDP),和一個方法來發送數據報:高流量的C#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));
}
}
}
}
所以基本上當有一名玩家時,會有大約60包/ s的IN和60包/ s的輸出。
它就像這樣:
- 偵聽分組。
- 驗證數據包。
- 處理數據包的數據 - >像存儲一些位置的,發回一些數據包...
所以它只是循環這樣。
及存在的問題在這裏:
首先,當有2名球員(主機+ 1Client),會有一些顯著FPS下降在某些時候,主機會經歷所有音頻的口吃(如藍色屏幕)片刻。其次,當有2個以上的玩家(主持人+ 1 +客戶端)時,主機FPS將下降到5-20,並且會滯後+滯後+滯後+滯後但並不凍結。
我讀過一些關於異步的文章,而且這已經是線程化的了?
而且還BeginRecieve
和EndRecieve
,我真的不明白如何以及爲什麼我需要使用它。
有人可以提供一些例子來解釋如何處理這些數據併發送/接收數據包嗎?我真的不想使用庫,因爲我想知道發生了什麼。
P.S:Terraria的網絡系統如何工作?它使用TCP,但它很流暢!怎麼樣?
PSS:什麼是緩衝?爲什麼我需要設置緩衝以及如何?它有什麼變化?
PSSS:我認爲在發送數據包時有一些需要調整和改變的地方,因爲它看起來很簡單。
「贏得比賽的唯一方法是根本不玩。」您不應該用大量數據淹沒網絡 - 只能在實際更改值時發送數據。此外,速率限制和客戶預測被用來避免這個非常相同的問題。老實說,在谷歌上2分鐘就會告訴你 - 給你個例子。 –
爲什麼你的回調是空的?至少你應該調用'udpClient.EndSend'來完成異步操作。這不是你昨天問過的基本相同的問題嗎? – spender
什麼是'ListenForClients'?它不在你的代碼中。 – spender