2

select() を使用してノンブロッキング TCP ソケット プログラミングを行っています。

通常のセットアップ後、

socket()
make socket non-blocking
bind()
listen()
FD_ZERO
FD_SET
  ...
select()

FD_ISSET
  ...
  s = accept()

特定の理由で、FD_ISSET の後、サーバーはいくつかの準備を行いますが、受け入れないことを選択します。簡単な方法は、accept() の後に s を閉じることです。しかし、accept() の前に、この接続が失敗する必要があることをクライアントに伝える方法はありますか? ありがとうございました。

4

1 に答える 1

4

いいえ。着信接続を取得した後、それが必要ない場合は、すぐに接続する必要がaccept()ありclose()ます。これは、TCP (または他のネットワーク プロトコル) の動作の結果ではありませんが、ソケット API に固有のものです

TCP/IP について話していると仮定すると、リッスンしているソケットが読み取りの準備ができていることを通知するまでにselect()(poll()または何でも)、接続を受け入れないには遅すぎることに注意してください。カーネルは既に受け入れています。あなたに代わって接続します。つまりSYN|ACK、着信SYNパケットに応答してすでに を送信しています。それは実際にはlisten()システムコールの効果です。その後、への呼び出しaccept()は形式的なものにすぎません。受け入れられた接続に新しいファイル記述子を割り当てます。

別の方法を利用する可能性のある最も注目すべきソフトウェアは、TCP ラッパーです。通常、TCP ラッパーは、リモート IP アドレスのみに基づいて着信接続を受け入れるかどうかを決定します。この決定を行い、接続が受け入れられる前に拒否する機会が与えられた場合、TCP ラッパーによって接続が拒否されたクライアントが、真の「接続拒否」応答 (パケットRSTへの応答、単に応答) を取得できるようになります。SYNポートでリッスンしているものがない場合と同じです)。しかし、ソケット インターフェイスでは、それを行う方法はありません。代わりに、クライアントの接続が開かれ、すぐに閉じられます。

すべてのオペレーティング システムがこのように同じというわけではありません。たとえば Cisco IOS で、vty ポートのアクセス リストを設定して、一部の IP アドレスからの着信接続を許可し、他の IP アドレスからの着信接続を拒否すると、拒否された接続は真の「接続拒否」になります。ただし、ソケットを使用して実装されていません。(おそらく、非常に独自のものを使用して実装されています。)

于 2013-02-01T21:27:15.917 に答える