21

接続を受け入れたい場合は に電話acceptしますが、接続を拒否するにはどうすればよいですか?

動作中のソケット エコー クライアントには、この if ステートメントがあります。printfエコー サーバーで、エコー クライアントをこのステートメント に到達させるにはどうすればよいですか?

...
if (connect(sock, (struct sockaddr *) &server, sizeof(server)) < 0) { 
    printf("Connecting failed\n"); 
    return 1; 
}
...
4

5 に答える 5

13

必要な動作 (一度に 1 つの接続のみを受け入れ、試行している他のクライアントは失敗する必要があります) を得るには、2 つの選択肢があります。

  • 接続を受け入れた後、リッスン ソケットを閉じることができます。受け入れられた接続が閉じた後、リッスン ソケットを再作成します。

  • 進行中の接続が既にある場合は、新しく確立された接続を閉じることができます。クライアントに TCP リセットを表示させたい場合、タイムアウト 0 で linger オプションを有効にすると、ほとんどの TCP スタックでトリガーされます。

    struct linger lo = { 1, 0 };
    setsockopt(s, SOL_SOCKET, SO_LINGER, &lo, sizeof(lo));
    close(s);

于 2013-05-16T15:20:45.850 に答える
8

私の知る限り、それはTCPの仕組みではありません。accept(..)電話は常にクライアントの詳細を返します。接続をのぞいて選択的に拒否する方法はありません。

あなたが現在行っている方法は、実際には正しい方法です: 受け入れてから閉じます。このレイヤーの上に別のメッセージ構造がある場合は、カスタムの「拒否メッセージ」を作成できます。このオプションは、ユースケースに完全に依存します。

IP アドレスに基づいて拒否する場合は、アプリ ドメイン内にありません。ファイアウォールの仕事です(@Bart Friederichsが言うように)。そうすれば、リクエストは TCP スタックに触れることさえありません。


実際には、この特定のポートでのみ厳密に 1 つの接続が必要です。他の接続は、理想的には非常に明白な方法で失敗するはずです。

制御フローで accept 呼び出しを行わないでください。あなたが待つときだけ、acceptあなたのプログラムはソケット接続を待ちます。

于 2013-05-16T15:08:40.943 に答える
5

ほとんどのプラットフォームの標準ソケット API では、接続を拒否する方法はありません。accept()接続が不要な場合は、接続をすぐに閉じる必要があります。

この規則の例外は、Winsock 固有のWSAAccept()関数です。これは、アプリケーションが接続ごとに、接続を受け入れるか、拒否するか、またはバックログ キューに保持するかを決定できるようにするコールバックを提供します。

于 2013-05-16T20:47:28.417 に答える
2

役に立つかもしれません

  1. accept()クライアント接続に成功した後、リッスンしているサーバー ソケットを閉じ、
  2. 何らかの理由でクライアント接続が切断された後に再確立します。
于 2013-05-16T15:12:40.297 に答える