これは、C、C++、C#、およびその他の言語用にプロトコルが変更された独立した ENet 実装です。
特徴:
よくある間違いを読んで、何が問題になる可能性があるかを理解してください。
ネイティブ ライブラリを構築するには、適切なソフトウェアが必要です。
デスクトップ プラットフォームの場合は、GNU Make または Visual Studio を使用した CMake。
モバイル プラットフォームの場合は、Android 用 NDK および iOS 用 Xcode。コンパイルされたすべてのライブラリが適切なプラットフォームと CPU アーキテクチャに割り当てられていることを確認してください。
Nintendo Switch 用のライブラリを構築するには、このガイドに従ってください。
マネージド アセンブリは、C# 3.0 以降をサポートする利用可能なコンパイル プラットフォームを使用してビルドできます。
コンパイルされたライブラリは、リリース セクションまたは NuGet から取得できます。
ENet-CSharp
.NET 環境 (.NET Standard 2.1) 用のネイティブ ライブラリを使用してコンパイルされたアセンブリが含まれています。
ENet-Unity
は、Unity のネイティブ ライブラリを含むスクリプトが含まれています。
バイナリを含むフォルダーを置き換えてアップグレードするのではなく、削除することを強くお勧めします。
これらのパッケージは、Windows、Linux、macOS (x64) などの従来のプラットフォームに対してのみ提供されます。
サポートされている OS バージョン:
作業を開始する前に、 ENet.Library.Initialize();
を使用してライブラリを初期化する必要があります。関数。
作業が完了したら、 ENet.Library.Deinitialize();
を使用してライブラリの初期化を解除します。関数。
using ( Host server = new Host ( ) ) {
Address address = new Address ( ) ;
address . Port = port ;
server . Create ( address , maxClients ) ;
Event netEvent ;
while ( ! Console . KeyAvailable ) {
bool polled = false ;
while ( ! polled ) {
if ( server . CheckEvents ( out netEvent ) <= 0 ) {
if ( server . Service ( 15 , out netEvent ) <= 0 )
break ;
polled = true ;
}
switch ( netEvent . Type ) {
case EventType . None :
break ;
case EventType . Connect :
Console . WriteLine ( "Client connected - ID: " + netEvent . Peer . ID + ", IP: " + netEvent . Peer . IP ) ;
break ;
case EventType . Disconnect :
Console . WriteLine ( "Client disconnected - ID: " + netEvent . Peer . ID + ", IP: " + netEvent . Peer . IP ) ;
break ;
case EventType . Timeout :
Console . WriteLine ( "Client timeout - ID: " + netEvent . Peer . ID + ", IP: " + netEvent . Peer . IP ) ;
break ;
case EventType . Receive :
Console . WriteLine ( "Packet received from - ID: " + netEvent . Peer . ID + ", IP: " + netEvent . Peer . IP + ", Channel ID: " + netEvent . ChannelID + ", Data length: " + netEvent . Packet . Length ) ;
netEvent . Packet . Dispose ( ) ;
break ;
}
}
}
server . Flush ( ) ;
}
using ( Host client = new Host ( ) ) {
Address address = new Address ( ) ;
address . SetHost ( ip ) ;
address . Port = port ;
client . Create ( ) ;
Peer peer = client . Connect ( address ) ;
Event netEvent ;
while ( ! Console . KeyAvailable ) {
bool polled = false ;
while ( ! polled ) {
if ( client . CheckEvents ( out netEvent ) <= 0 ) {
if ( client . Service ( 15 , out netEvent ) <= 0 )
break ;
polled = true ;
}
switch ( netEvent . Type ) {
case EventType . None :
break ;
case EventType . Connect :
Console . WriteLine ( "Client connected to server" ) ;
break ;
case EventType . Disconnect :
Console . WriteLine ( "Client disconnected from server" ) ;
break ;
case EventType . Timeout :
Console . WriteLine ( "Client connection timeout" ) ;
break ;
case EventType . Receive :
Console . WriteLine ( "Packet received from server - Channel ID: " + netEvent . ChannelID + ", Data length: " + netEvent . Packet . Length ) ;
netEvent . Packet . Dispose ( ) ;
break ;
}
}
}
client . Flush ( ) ;
}
Packet packet = default ( Packet ) ;
byte [ ] data = new byte [ 64 ] ;
packet . Create ( data ) ;
peer . Send ( channelID , ref packet ) ;
byte [ ] buffer = new byte [ 1024 ] ;
netEvent . Packet . CopyTo ( buffer ) ;
AllocCallback OnMemoryAllocate = ( size ) => {
return Marshal . AllocHGlobal ( size ) ;
} ;
FreeCallback OnMemoryFree = ( memory ) => {
Marshal . FreeHGlobal ( memory ) ;
} ;
NoMemoryCallback OnNoMemory = ( ) => {
throw new OutOfMemoryException ( ) ;
} ;
Callbacks callbacks = new Callbacks ( OnMemoryAllocate , OnMemoryFree , OnNoMemory ) ;
if ( ENet . Library . Initialize ( callbacks ) )
Console . WriteLine ( "ENet successfully initialized using a custom memory allocator" ) ;
使い方は.NET環境とほぼ同じですが、コンソールの機能をUnityが提供する機能に置き換える必要があります。 Host.Service()
がゲーム ループで呼び出される場合は、タイムアウト パラメーターが非ブロッキングを意味する 0 に設定されていることを確認してください。また、プレーヤー設定で適切なオプションを有効にして、Unity をバックグラウンドで実行し続けます。
最もよく知られている戦略は、独立した I/O スレッドで ENet を使用し、ロック/ミューテックスを使用せずにスレッド/タスク間でデータを転送するためのスレッド間メッセージング技術を利用することです。リング バッファのようなノンブロッキング キューは、そのような目的のために設計されました。高レベルの抽象化とロジックはワーカーを使用して並列化し、I/O スレッドと通信し、メッセージをキューに入れたり、キューから取り出したりして、ネットワーク全体でデータを送受信できます。
一般に、ENet はスレッドセーフではありませんが、ユーザーが十分に注意していれば、一部の機能は安全に使用できます。
パケットが値によってのみスレッド間を移動し、カスタム メモリ アロケータが使用されない限り、 Packet
構造とその機能は安全です。
Peer.ID
ピアへのポインタがネイティブ側から取得されるとすぐに、その ID に割り当てられたオブジェクトに対するさらなるアクションのために、ID がPeer
構造にキャッシュされます。 Peer
構造は値によってスレッド間で移動できますが、メモリ内のデータが別のスレッドのサービスによって変更される可能性があるため、その関数はスレッドセーフではありません。
Library.Time
ローカル単調時間を管理するために内部でアトミック プリミティブを利用します。
Peer.Send()
関数のフラグの定義:
PacketFlags.None
シーケンスの信頼性が低く、パケットの配信は保証されません。
PacketFlags.Reliable
信頼性の高い順序付け、パケットはターゲット ピアによって受信される必要があり、パケットが配信されるまで再送試行が行われる必要があります。
PacketFlags.Unsequenced
パケットは他のパケットと順序付けられず、順序が崩れて配信される可能性があります。このフラグにより、配信の信頼性が低くなります。
PacketFlags.NoAllocate
パケットはデータを割り当てないため、代わりにユーザーがデータを指定する必要があります。パケットの有効期間は、 PacketFreeCallback
コールバックを使用して追跡する必要があります。
PacketFlags.UnreliableFragmented
パケットは、MTU を超えると信頼性が低く断片化されます。デフォルトでは、MTU を超える信頼性の低いパケットは断片化され、確実に送信されます。このフラグは、信頼性の低いままにするパケットを明示的に示すために使用する必要があります。
PacketFlags.Instant
パケットは、次のサービス反復時に他のパケットにバンドルされず、代わりに即座に送信されます。この配信タイプでは、遅延を優先して多重化効率を犠牲にします。同じパケットを複数のPeer.Send()
呼び出しに使用することはできません。
PacketFlags.Unthrottled
信頼性の低い送信のためにキューに入れられたパケットは、可能であればスロットルによってドロップされずに送信されるべきです。
PacketFlags.Sent
パケットは、入力されたすべてのキューから送信されました。
Event.Type
プロパティのイベント タイプの定義:
EventType.None
指定された制限時間内にイベントは発生しませんでした。
EventType.Connect
Peer.Connect()
関数によって開始された接続要求が完了しました。 Event.Peer
接続に成功したピアを返します。 Event.Data
接続を説明するユーザー指定のデータを返します。利用可能なデータがない場合は 0 を返します。
EventType.Disconnect
ピアが切断されました。このイベントは、 Peer.Disconnect()
関数によって開始された切断が正常に完了すると生成されます。 Event.Peer
切断されたピアを返します。 Event.Data
切断を説明するユーザー指定のデータを返します。利用可能なデータがない場合は 0 を返します。
EventType.Receive
ピアからパケットを受信しました。 Event.Peer
パケットを送信したピアを返します。 Event.ChannelID
パケットが受信されたチャネル番号を指定します。 Event.Packet
受信したパケットを返します。このパケットは使用後にEvent.Packet.Dispose()
関数を使用して破棄する必要があります。
EventType.Timeout
ピアがタイムアウトしました。このイベントは、ピアがタイムアウトした場合、またはPeer.Connect()
によって初期化された接続要求がタイムアウトした場合に発生します。 Event.Peer
タイムアウトしたピアを返します。
Peer.State
プロパティのピア状態の定義:
PeerState.Uninitialized
ピアが初期化されていません。
PeerState.Disconnected
ピアが切断されたかタイムアウトになりました。
PeerState.Connecting
ピア接続が進行中です。
PeerState.Connected
ピアが正常に接続されました。
PeerState.Disconnecting
ピア切断が進行中です。
PeerState.Zombie
ピアが正しく切断されていません。
アプリケーションごとのイベントを提供します。
AllocCallback(IntPtr size)
メモリの割り当てが要求されたときに通知します。新しく割り当てられたメモリへのポインタが必要です。デリゲートへの参照は、ガベージ コレクションから保護される必要があります。
FreeCallback(IntPtr memory)
メモリが解放できる時期を通知します。デリゲートへの参照は、ガベージ コレクションから保護される必要があります。
NoMemoryCallback()
メモリが十分でない場合に通知します。デリゲートへの参照は、ガベージ コレクションから保護される必要があります。
パケットごとのイベントを提供します。
PacketFreeCallback(Packet packet)
パケットが破棄されるときに通知します。信頼できるパケットが確認応答されたかどうかを示します。デリゲートへの参照は、ガベージ コレクションから保護される必要があります。
ホストごとのイベントを提供します。
InterceptCallback(ref Event @event, ref Address address, IntPtr receivedData, int receivedDataLength)
生の UDP パケットがインターセプトされたときに通知します。このコールバックから返されるステータス コードは、設定されたイベントの処理方法を ENet に指示します。 1 が返されると、サービスによる設定されたイベントのディスパッチが示されます。 0 を返すと、ENet サブシステムが受信データを処理する必要があることを示します。 -1 を返すとエラーを示します。デリゲートへの参照は、ガベージ コレクションから保護される必要があります。
ChecksumCallback(IntPtr buffers, int bufferCount)
送信時および受信時にバッファーのチェックサムを計算する必要がある場合に通知します。このコールバックから返される値は 64 ビットのチェックサムです。チェックサム メカニズムが両端で有効になっている場合、ENet はパケットの整合性検証を自動的に処理します。 ENet.Library.CRC64()
関数とともに使用できます。デリゲートへの参照は、ガベージ コレクションから保護される必要があります。
匿名のホスト データとポート番号を含む構造が含まれます。
Address.Port
ポート番号を取得または設定します。
Address.GetIP()
IP アドレスを取得します。
Address.SetIP(string ip)
IP アドレスを設定します。ローカル ネットワークで IPv4 ブロードキャストを使用するには、クライアントのアドレスを255.255.255.255に設定します。 ENet はブロードキャストに自動的に応答し、アドレスをサーバーの実際の IP に更新します。
Address.GetHost()
アドレスから逆引き参照を実行しようとします。解決された名前または IP アドレスを含む文字列を返します。
Address.SetHost(string hostName)
ホスト名または IP アドレスを設定します。ネットワーク インターフェイスへのバインドまたは外部ホストへの接続に使用する必要があります。成功した場合は true を返し、失敗した場合は false を返します。
イベント タイプ、ピアへの管理対象ポインタ、チャネル ID、ユーザー指定のデータ、およびパケットへの管理対象ポインタを含む構造体が含まれます。
Event.Type
イベントのタイプを返します。
Event.Peer
、接続、切断、受信、またはタイムアウト イベントを生成したピアを返します。
Event.ChannelID
必要に応じて、イベントを生成したピアのチャネル ID を返します。
Event.Data
必要に応じて、ユーザーが指定したデータを返します。
Event.Packet
必要に応じて、イベントに関連付けられたパケットを返します。
パケットへのマネージド ポインタが含まれます。
Packet.Dispose()
パケットを破棄します。パケットがEventType.Receive
イベントから取得された場合にのみ呼び出される必要があります。
Packet.IsSet
マネージド ポインタの状態を返します。
Packet.Data
パケット データへのマネージド ポインターを返します。
Packet.UserData
ユーザーが指定したデータを取得または設定します。
Packet.Length
パケット内のペイロードの長さを返します。
Packet.HasReferences
パケットへの参照をチェックします。
Packet.SetFreeCallback(PacketFreeCallback callback)
適切なパケットが破棄されるときに通知するコールバックを設定します。コールバックへのポインターIntPtr
、デリゲートへの参照の代わりに使用できます。
Packet.Create(byte[] data, int offset, int length, PacketFlags flags)
ピアに送信できるパケットを作成します。 offset パラメータは配列内のデータの開始点を示し、長さは配列内のデータの終了点を示します。すべてのパラメータはオプションです。複数のパケットフラグを一度に指定できます。バイト配列への参照の代わりに、ネイティブ バッファへのポインタIntPtr
使用できます。
Packet.CopyTo(byte[] destination)
ペイロードをパケットから宛先配列にコピーします。
ピアへのマネージド ポインタとキャッシュされた ID が含まれます。
Peer.IsSet
マネージド ポインターの状態を返します。
Peer.ID
ピア ID を返します。クライアント側では常にゼロです。
Peer.IP
印刷可能な形式で IP アドレスを返します。
Peer.Port
ポート番号を返します。
Peer.MTU
MTU を返します。
Peer.State
PeerState
列挙で記述されたピア状態を返します。
Peer.RoundTripTime
往復時間をミリ秒単位で返します。
Peer.LastRoundTripTime
、最後の確認応答からの往復時間をミリ秒単位で返します。
Peer.LastSendTime
最後のパケット送信時間をミリ秒単位で返します。
Peer.LastReceiveTime
最後のパケット受信時間をミリ秒単位で返します。
Peer.PacketsSent
接続中に送信されたパケットの合計数を返します。
Peer.PacketsLost
再送信ロジックに基づいて、接続中に失われたとみなされるパケットの総数を返します。
Peer.PacketsThrottle
ピアへの接続の条件に応じてパケット スロットルの比率を返します。
Peer.BytesSent
接続中に送信された合計バイト数を返します。
Peer.BytesReceived
接続中に受信した合計バイト数を返します。
Peer.Data
ユーザーが指定したデータを取得または設定します。適切なデータ型に明示的にキャストして使用する必要があります。
Peer.ConfigureThrottle(uint interval, uint acceleration, uint deceleration, uint threshold)
ピアのスロットル パラメーターを構成します。信頼性の低いパケットは、ピアへの接続のさまざまな条件に応じて ENet によってドロップされます。スロットルは、信頼性の低いパケットがドロップされず、ENet によってピアに送信されるべきではない確率を表します。信頼性の高いパケットの送信から確認応答の受信までの最小平均ラウンドトリップ時間は、ミリ秒単位の間隔パラメータで指定された時間にわたって測定されます。測定されたラウンドトリップ時間が、その間隔で測定された平均ラウンドトリップ時間よりも大幅に短かった場合、スロットル確率が増加して、加速パラメータで指定された量 ( Library.throttleScale
に対する比率) だけより多くのトラフィックが許可されます。 Library.throttleScale
定数。測定された往復時間がたまたまその間隔で測定された平均往復時間を大幅に上回った場合、スロットル確率が減少して、減速パラメータで指定された量 ( Library.throttleScale
定数。スロットルの値がLibrary.throttleScale
の場合、信頼性の低いパケットは ENet によってドロップされないため、すべての信頼性のないパケットの 100% が送信されます。スロットルの値が 0 の場合、信頼性の低いパケットはすべて ENet によってドロップされるため、信頼性の低いすべてのパケットの 0% が送信されます。スロットルの中間値は、送信される信頼性の低いパケットの 0% と 100% の間の中間の確率を表します。ローカルおよび外部ホストの帯域幅制限を考慮して、スロットル確率の適切な制限を決定します。この制限を超えては、たとえ最良の条件であっても、この制限を超えてはなりません。スロットルを無効にするには、減速パラメータをゼロに設定する必要があります。しきい値パラメーターを使用すると、混雑した場所の Wi-Fi ネットワークで一般的な条件である、ジッターが高く平均遅延が低い不安定なネットワーク環境において、測定されたラウンドトリップ時間に対するパケット スロットリングを減らすことができます。デフォルトでは、しきい値パラメーターはミリ秒単位でLibrary.throttleThreshold
に設定されます。
Peer.Send(byte channelID, ref Packet packet)
送信されるパケットをキューに入れます。成功した場合は true を返し、失敗した場合は false を返します。
Peer.Receive(out byte channelID, out Packet packet)
キューに入っている受信パケットをデキューしようとします。パケットがデキューされた場合は true を返し、利用可能なパケットがない場合は false を返します。
Peer.Ping()
ピアに ping リクエストを送信します。 ENet は、接続されているすべてのピアに定期的に自動的に ping を送信しますが、この関数は、より頻繁な ping 要求を確実に行うために呼び出される場合があります。
Peer.PingInterval(uint interval)
ピアに ping が送信される間隔を設定します。 ping は、接続の稼働状況を監視するためと、トラフィックが急増したときにスロットルが適切な応答性を持つように、トラフィックが少ないときにスロットルを動的に調整するために使用されます。
Peer.Timeout(uint timeoutLimit, uint timeoutMinimum, uint timeoutMaximum)
ピアのタイムアウト パラメーターを設定します。タイムアウト パラメータは、信頼できるトラフィックの確認応答に失敗した場合にピアがタイムアウトする方法とタイミングを制御します。半線形メカニズムで使用されるタイムアウト値。信頼できるパケットが、平均ラウンドトリップ時間に分散許容差を加えた時間内に確認応答されなかった場合、タイムアウトが設定された制限に達するまでの値です。したがって、タイムアウトがこの制限に達し、信頼できるパケットが送信されたにもかかわらず、特定の最小期間内に確認応答されなかった場合、ピアは切断されます。あるいは、信頼できるパケットが送信されたにもかかわらず、一定の最大期間にわたって確認応答がなかった場合、現在のタイムアウト制限値に関係なく、ピアは切断されます。
Peer.Disconnect(uint data)
ピアからの切断を要求します。
Peer.DisconnectNow(uint data)
ピアからの即時切断を強制します。
Peer.DisconnectLater(uint data)
キューに入れられたすべての送信パケットが送信された後にのみ、ピアからの切断を要求します。
Peer.Reset()
ピアを強制的に切断します。ピアによって表される外部ホストには切断が通知されず、ローカル ホストへの接続がタイムアウトになります。
ホストへのマネージド ポインタが含まれます。
Host.Dispose()
ホストを破棄します。
Host.IsSet
マネージド ポインターの状態を返します。
Host.PeersCount
接続されているピアの数を返します。
Host.PacketsSent
セッション中に送信されたパケットの合計数を返します。
Host.PacketsReceived
セッション中に受信したパケットの総数を返します。
Host.BytesSent
セッション中に送信された合計バイト数を返します。
Host.BytesReceived
セッション中に受信した合計バイト数を返します。
Host.Create(Address? address, int peerLimit, int channelLimit, uint incomingBandwidth, uint outgoingBandwidth, int bufferSize)
ピアと通信するためのホストを作成します。帯域幅パラメータは接続のウィンドウ サイズを決定し、任意の時点で送信される可能性がある信頼できるパケットの数を制限します。 ENet は、ホスト間の接続の特定側で戦略的にパケットをドロップし、ホストの帯域幅が過剰にならないようにします。バッファ サイズ パラメータは、データグラムの送受信用のソケット バッファ サイズを設定するために使用されます。着信接続をリッスンするホストを作成するために関数が使用される場合のアドレスとピア制限を除くすべてのパラメーターはオプションです。
Host.PreventConnections(bool state)
新しい受信接続によるホストへのアクセスを防止します。この機能により、ホストはネットワーク内で完全に見えなくなり、それに接続しようとするピアはタイムアウトになります。
Host.Broadcast(byte channelID, ref Packet packet, Peer[] peers)
一定範囲のピア、またはオプションのピア パラメータが使用されていない場合はホストに関連付けられているすべてのピアに送信されるパケットをキューに入れます。配列内のゼロ化されたPeer
構造はブロードキャストから除外されます。配列の代わりに、ブロードキャストから除外される単一のPeer
関数に渡すことができます。
Host.CheckEvents(out Event @event)
ホスト上のキューにあるイベントをチェックし、利用可能な場合はイベントをディスパッチします。イベントがディスパッチされた場合は > 0、利用可能なイベントがない場合は 0、失敗した場合は < 0 を返します。
Host.Connect(Address address, int channelLimit, uint data)
外部ホストへの接続を開始します。成功した場合は外部ホストを表すピアを返し、失敗した場合は例外をスローします。返されたピアは、 Host.Service()
がEventType.Connect
イベントを通知するまで接続を完了しません。チャネル制限とユーザー指定のデータ パラメーターはオプションです。
Host.Service(int timeout, out Event @event)
指定されたホスト上のイベントを待機し、ホストとそのピアの間でパケットをやり取りします。 ENet は、ポーリング イベント モデルを使用して、重要なイベントをユーザーに通知します。 ENet ホストは、この関数を使用してイベントについてポーリングされます。オプションのタイムアウト値をミリ秒単位で指定して、ENet がポーリングする時間を制御できます。タイムアウトに 0 が指定されている場合、送出するイベントがない場合、この関数はすぐに戻ります。それ以外の場合、指定されたタイムアウト内にイベントがディスパッチされた場合は 1 を返します。この関数は、パケットが確実に送受信されるように定期的に呼び出す必要があります。そうしないと、トラフィックのスパイクが発生し、遅延が増加します。タイムアウト パラメーターを 0 に設定すると、関数がゲーム ループで呼び出される場合に必要な非ブロッキングを意味します。
Host.SetBandwidthLimit(uint incomingBandwidth, uint outgoingBandwidth)
ホストの帯域幅制限を 1 秒あたりのバイト数で調整します。
Host.SetChannelLimit(int channelLimit)
今後の受信接続で許可される最大チャネルを制限します。
Host.SetMaxDuplicatePeers(ushort number)
同じホストから許可される重複ピアの最大数を制限し、超過した場合は接続を禁止します。デフォルトではLibrary.maxPeers
に設定され、1 未満にすることはできません。
Host.SetInterceptCallback(InterceptCallback callback)
生の UDP パケットがインターセプトされたときに通知するコールバックを設定します。コールバックへのポインターIntPtr
、デリゲートへの参照の代わりに使用できます。
Host.SetChecksumCallback(ChecksumCallback callback)
チェックサムを計算する必要がある場合に通知するコールバックを設定します。コールバックへのポインターIntPtr
、デリゲートへの参照の代わりに使用できます。
Host.Flush()
指定されたホスト上のキューに入れられたパケットを指定されたピアに送信します。
定数フィールドが含まれます。
Library.maxChannelCount
可能な最大チャネル数。
Library.maxPeers
可能なピアの最大数。
Library.maxPacketSize
パケットの最大サイズ。
Library.version
ネイティブ ライブラリに対する現在の互換性バージョン。
Library.Time
現在のローカル単調時間をミリ秒単位で返します。アプリケーションが生きている間はリセットされません。
Library.Initialize(Callbacks callbacks)
ネイティブ ライブラリを初期化します。 Callbacks パラメータはオプションであり、カスタム メモリ アロケータでのみ使用する必要があります。作業を開始する前に電話する必要があります。成功した場合は true を返し、失敗した場合は false を返します。
Library.Deinitialize()
ネイティブ ライブラリを初期化解除します。作業が完了したら電話する必要があります。
Library.CRC64(IntPtr buffers, int bufferCount)
アンマネージ バッファのチェックサムを計算します。
このプロジェクトは以下によって後援されています。
ムササビエンターテイメント
平方根スタジオ
ストレンジ ループ ゲーム