- 締切済み
ソケット通信で接続クライアントの上限を設ける
(Unix c言語) ソケット通信で、サーバに接続するクラインとの上限をきめてそれ以上の数の接続要求があった場合、そのクライアントに対しての接続を拒否するには、サーバ側とクライアント側でどのような書き方をすればいいでしょうか?
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- chirubou
- ベストアンサー率37% (189/502)
すいません、補足を見逃してました。もう解決済みかな? クライアントの上限を超えたら、accept() してそのまま close() すれば OK です。クライアント側では connect() が失敗してきます。 accept() ではコネクトしてきた相手の IP アドレス等がチェックできるようになってますよね?もしそうしたいなら、チェックしてダメな相手だったら close() してしまえば OK です。 これは一見おかしいようにも思えますが、ソケットのコネクションの本当の完了は、実際の通信が行われる時まで遅延されているので、上記の方法で大丈夫なのです。
- chirubou
- ベストアンサー率37% (189/502)
No.1 さんのだと、最初の N 接続だけを可能とする、というようになりかねません。もし「仕様」が接続しているクライアントの最大数を制限する、というのであれば、処理はもう少し複雑になります。 ここで、普通のクライアント、サーバ型の処理形態だとすると、接続要求をサーバが受け付けた時には子プロセスを fork() しますよね。で、処理が終わったら子プロセスは終了しますよね。 つまり接続している数だけ子プロセスが存在することになるので、子プロセスの数を制限すれば良いことになります。つまり、子プロセス生成時にカウンタをインクリメントし、子プロセスの終了時にカウンタをデクリメントし、カウンタの上限を超えたかどうかをチェックすれば実現できることになります。 このためには子プロセスの終了をサーバが感知する必要があります。これには wait*() を WNOHANG オプション付きで定期的に呼び出すか、シグナルハンドラを設定して、SIGCHLD シグナルを拾うとかする必要があります。
- tatsu99
- ベストアンサー率52% (391/751)
クライアント側で接続拒否の理由を知る必要がないなら、クライアント側は、ふつうにコネクトすれば、良いと思います。 サーバ側が、アクセプト時に、アクセプトしたソケットの数を数えて、それが上限に達していれば、直ちにそのソケットをクローズすれば、良いと思います。
補足
>カウンタの上限を超えたかどうかをチェックすれば実現できることになります。 具体的にはカウンタの上限を超えたら、どのように記述すればいいのでしょうか?サーバ側ではただ単にaccept行を飛ばすようにすればいいんでしょうか?クライアント側ではconnectをノンブロッキングにする必要もありますか?