この問題を処理するにはさまざまな方法があります。どちらを選択するかは、実行したい作業の量によって異なります。*
ただし、最初に、UDP と TCP のどちらを扱っているかを (自分自身で) 明確にする必要があります。UDP ソケットの「基礎となる TCP スタック」はありません。また、UDP は、テキストや写真などのデータ全体を送信するために使用するプロトコルとしては不適切です。これは信頼性の低いプロトコルであるため、マネージ ソケット ライブラリ ( ENetなど) を使用していない限り、すべてのパケットを受信できる保証はありません。
Lua51/LuaJIT + LuaSocket
ポーリングが唯一の方法です。
- ブロッキング:
socket.select
時間引数なしで呼び出し、ソケットが読み取り可能になるまで待機します。
- ノンブロッキング:
socket.select
のタイムアウト引数を指定して呼び出し、読み取り元のソケット0
で使用sock:settimeout(0)
します。
次に、これらを繰り返し呼び出すだけです。ノンブロッキング バージョンではコルーチン スケジューラを使用することをお勧めします。これにより、プログラムの他の部分があまり遅延することなく実行を継続できるようになります。
Lua51/LuaJIT + LuaSocket + Lua レーン(推奨)
上記の方法と同じですが、Lua Lanes (最新ソース) を使用して作成された別のレーン (別のスレッドの軽量 Lua 状態) にソケットが存在します。これにより、データをソケットからバッファに即座に読み取ることができます。次に、lindaを使用してデータを処理のためにメイン スレッドに送信します。
これはおそらくあなたの問題に対する最良の解決策です。
これの簡単な例を作成しました。こちらから入手できます。これは、Lua Lanes 3.4.0 ( GitHub リポジトリ) と、パッチが適用された LuaSocket 2.0.2 (ソース、パッチ、ブログ投稿 re' patch )に依存しています。
結果は有望ですが、このサンプル コードから派生する場合は、間違いなくリファクタリングする必要があります。
LuaJIT + OS 固有のソケット
少しマゾヒスティックな人は、ソケット ライブラリをゼロから実装してみることができます。LuaJITのFFI ライブラリは、純粋な Lua からこれを可能にします。Lua Lanes はこれにも役立ちます。
Windows については、 William Adam のブログを参照することをお勧めします。彼は、LuaJIT と Windows の開発に関して非常に興味深い冒険をしてきました。Linux などについては、C のチュートリアルや LuaSocket のソースを見て、LuaJIT FFI 操作に翻訳してください。
(LuaJIT は、API が必要とする場合、コールバックをサポートします。ただし、Lua から C へのポーリングと比較して、パフォーマンス コストが大幅に低下します。)
LuaJIT + ENet
ENetは優れたライブラリです。TCP と UDP の完璧な組み合わせを提供します。また、LuaSocket と同様に、オペレーティング システム固有の詳細を抽象化します。Lua API を使用してバインドするか、LuaJIT の FFI (推奨) 経由で直接アクセスできます。
※意図しないしゃれ。