5

簡単に言えば、私の質問は、アクティブな接続が1つしかないtcpサーバーがある場合、サーバー側のデータソケットを1つ作成するだけでよいということです。すべてのチュートリアルで、新しいソケットが作成されていることがわかりますが、なぜこれが必要なのかわかりません。サーバー側のソケットを1つ作成してから、それを開いたり、閉じたり、リセットしたりしないのはなぜですか?

さらに詳細に:

非同期デイタイムサーバーのブースト asio チュートリアルを実行して、コンパイルして動作させることができました。アプリケーション用に変更して、希望どおりに実行することもできます:)。しかし、私の最初のアプローチはうまくいきませんでした。なぜ私があなたの助けを求めていたのか理解できません.

基本的に、最初のクライアントが切断されない限り、1 つの TCP クライアントのみを受け入れ、他のすべてを無視する TCP サーバーを作成したいと考えていました。これを acceptor.close() と acceptor.open() を使用して行ったので、最初の接続が受け入れられたときにアクセプターを閉じ、eof エラーを検出するたびにアクセプターを再度開いて新しい接続をリッスンしました。私は単純に、アクティブな接続が 1 つだけ必要だったので、作成する必要があるのは 1 つだけだと考えました。

boost::asio::ip::tcp::socket socket_

クライアントからデータを受信するデータ ソケットは 1 つしかないため、チュートリアルに従って、tcp_connection クラス全体を作成するのはやり過ぎのようです。(チュートリアルでは、サーバーが新しい接続を受け入れるたびに、このコードを使用して新しいソケットが作成されると思います):

class tcp_connection
  : public boost::enable_shared_from_this<tcp_connection>
{
 public:
  typedef boost::shared_ptr<tcp_connection> pointer;

  static pointer create(boost::asio::io_service& io_service)
  {
    return pointer(new tcp_connection(io_service));
  }

  tcp::socket& socket()
  {
    return socket_;
  }


 private:
  tcp_connection(boost::asio::io_service& io_service)
    : socket_(io_service)
  {
  }

  tcp::socket socket_;
  std::string message_;
};

したがって、boost::asio::ip::tcp::socket を 1 つだけ使用しようとしました。上記のチュートリアルと同様の方法で io_service を使用して、サーバー クラスのコンストラクターでこれを初期化しました。私のテストでは、最初のクライアントが接続され、最初のクライアントが切断された後にのみ 2 番目のクライアントが接続されることが示されました。ただし、何をしたかに関係なく、 async_accept(socket_,.....) 呼び出しでデータ バッファーがいっぱいになることはありません。最初はeofエラーが発生し続けましたが、その後、ソックスを閉じて再度開いてみると、eofエラーが削除され、トランスポートが接続されていないというエラーが発生しました。明らかに、私はここで非常にばかげたことをしていますが、私がやろうとしていることについて哲学的に言えば、何が間違っているのかわかりません。チュートリアルの手法を使用して新しいソケットを作成すると、すべてが期待どおりに機能します。

だから私の質問は、ソケットを 1 つだけ持って、キャンセル、クローズ、オープンなどを行うことができるかということです。私はバインドまたは何か他のものを意図していますが、それは async_accept ジョブではありませんか?

ブースト asio を使用してまだ 1 週間しか経っていませんが、このようなフォーラムへの投稿はこれが初めてなので、気楽にどうぞ ;) .

4

1 に答える 1

3

できますが、できません。

あなたが述べたようにTCPを実装できない理由はありませんが、私が知っているオペレーティングシステムはそうではありません。

理由は非常に単純で、OSは複数の同時接続をサポートする必要があり、それが実装を決定する設計要件です。「存在できるのは 1 つだけ」のケースを実現するには、新しい接続を正常に受け入れた後にリスナー ソケットを閉じ、後で再度開きます。通常、そうするために努力する価値はありません。

あなたが説明するオーバーヘッドは最小限であり、最適化を試みる価値はありません。

于 2012-10-19T18:37:57.180 に答える