私は、ポジション(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)
{
}
リスナークラスは、ちょうど1つの非常に単純です:
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パケット/秒と60パケット/秒があります。それは、このような役割を果たし
:
- は、パケットのために聞いてください。
- パケットを検証します。
- プロセスパケットデータ - > ...、ポジションの一部を保存するいくつかのパケットを送り返すよう
だから、このような単なるループ。
まず、2人のプレイヤー(ホスト+ 1Client)がある場合、いくつかの重要なFPSはいくつかの点で低下があるでしょう、そしてホストはブルーのようにすべてのオーディオの吃音を(経験します:
そして、問題はここにあります画面)を表示します。
第2に、2人以上のプレイヤー(ホスト+ 1 +クライアント)がいる場合、ホストFPSは5-20に低下し、ラグ+ラグ+ラグ+ラグではなくフリーズします。
私はasyncに関するいくつかの記事を読んでいますが、これは既にスレッド化されていますか?
また、BeginRecieve
とEndRecieve
でも、どうやってそれを使用する必要があるのかよく分かりません。
これらの種類のデータを処理してパケットを送受信する方法を説明するためにいくつかの例がありますか?何が起こっているのか知りたいので、私は本当に図書館を使いたくない。
P.S:Terrariaのネットワークシステムはどのように機能しますか?それはTCPを使用しますが、それはスムーズです!どうやって?
PSS:バッファリングとは何ですか?なぜバッファリングを設定する必要がありますか?何が変わるのですか?
PSSS:パケットを送信する際に調整して変更するものがあると思います。
"ゲームに勝つ唯一の方法は、まったく遊ばないことです。"大量のデータをネットワークに流すべきではありません。値が実際に変更されたときにのみデータを送信します。さらに、この非常に同じ問題を回避するために、レート制限とクライアント予測が使用されています。正直なところ、Googleで2分間はあなたに言いました - そして例を挙げましょう。 –
コールバックが空白なのはなぜですか?少なくとも、udpClient.EndSendを呼び出して非同期操作を完了させる必要があります。これは基本的にあなたが昨日尋ねたのと同じ質問ですか? – spender
'ListenForClients'とは何ですか?どこのコードにもない。 – spender