私はまだ C ソケット プログラミングに慣れていませんが、いくつかの簡単なクライアント プログラムとサーバー プログラムを作成することができました。TCP接続をリッスンするサーバーをプログラミングしています。その義務は、クライアントの要求に応答し、クライアントが特別なバイトシーケンスを送信したとき(またはもちろん切断したとき)に通信を閉じます。
無限ループ内で関数を使用してサーバーのコーディングを開始しましたaccept()
。サーバーはクライアントを待機し、accept() でそれを処理し、すべてを実行し、最後にソケット記述子を close() して、再び受け入れを待って戻ります。新しいクライアント。
一度に 1 つのクライアントにサービスを提供したいので、listen 関数を次のように呼び出しました。listen(mysocket, 1);
すべてうまくいきましたが、新しい問題が発生しました。上で説明したサーバー部分は別のスレッド (スレッド #2 と呼びましょう) で実行され、メイン スレッド (スレッド #1) はそれを終了するように伝えることができなければなりません。次に、グローバル変数を作成しました。この変数が (スレッド #1 によって) 1 に設定されている場合、スレッド #2 は終了する必要があります。問題は、関数が呼び出されたときにスレッド #2 がスタックしaccept()
、グローバル変数を定期的にチェックできないことです。
その関数のタイムアウト値が明らかに必要でした。「受け入れる接続がない場合は、グローバル変数の値を確認し、0 に設定されている場合は新しい接続を待ち続け、1 に設定されている場合は終了します」。
そのとき、解決策をグーグルで検索したところ、select()
関数が必要なことを実行することがわかりました。少し違いますがfd_set
、FD_* マクロを初めて発見しました。サーバー部分を変更してselect()
関数で動作するようにしましたが、すべてがうまく機能しますが、ここで最後の問題が発生します。これは私が解決できない問題です。この方法でリッスン関数を呼び出した場合:listen(socket, 1);
ただし、サーバーは引き続き複数の接続を受け入れて同時に処理します。これは依存しますかselect()
fd_set で動作しますか? Web で見つけたいくつかの例を使用しています。接続が受け入れられると、他のすべてのセットに含まれる新しいソケット記述子が作成されます。1 つのクライアントだけの接続を受け入れたいのですが、接続しているクライアントにサービスを提供する必要があるかどうかを認識する簡単なコードを書きましたが、サーバー側で接続を切断する方法はありますか? close()
関数を使用してソケット記述子を閉じる必要があることはわかっていますが、使用するときselect()
に fd_set を操作していて、それらを閉じるために何をすべきか本当にわかりません。または、セット内のソケット記述子の数を制限する方法はありますか? FD_SETSIZE マクロを見つけましたが、それを機能させることができず、問題が解決するかどうかさえわかりません。
お時間をいただきありがとうございます!