3

だから私はboost::asioを試していて、ブロッキングエコーの例をテストしました。彼らは完全にブロックしていないようです。少なくとも私が期待した方法ではありません。

あらゆる種類のバッファリングを取り除くことは可能ですか? または、使用できる最小のバッファ サイズはどれくらいですか? 10000 バイトでは小さすぎるようです。

次のコードは、ブロックする前に 2 回の書き込みを実行します。書き込みに boost::asio::transfer_exactly(10000) 引数を追加しても、まだ 2 です。boost::asio::transfer_exactly(5000) は 5 回の書き込みを取得します。

では、このネットワーキング/io/asio はどのように機能するのでしょうか? たとえば、1 バイトだけ送信して、追加の通信を行わずに、相手に到達するのを待ちたいとします。

サーバ:

boost::asio::io_service io_service;

tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), 12346));
tcp::socket sock(io_service);

a.accept(sock);
sock.non_blocking(false);
boost::asio::socket_base::send_buffer_size option(10000);
sock.set_option(option);

while(true) {
    char data[10000];

    boost::asio::socket_base::bytes_readable bytes_readable_cmd(true);
    sock.io_control(bytes_readable_cmd);
    std::size_t bytes_readable = bytes_readable_cmd.get();
    if(bytes_readable) {
        /**/
    }

    boost::asio::write(sock, boost::asio::buffer(data, 10000));
    printf("#\n");Sleep(10);
}

クライアント:

boost::asio::io_service io_service;

tcp::resolver resolver(io_service);
tcp::resolver::query query(tcp::v4(), "localhost", "12346");
tcp::resolver::iterator iterator = resolver.resolve(query);

tcp::socket sock(io_service);
boost::asio::connect(sock, iterator);
sock.non_blocking(false);
4

1 に答える 1

5

writeこの場合、実際には、基になるバッファーがいっぱいになったときにのみブロックされると思います。

msdnからのこの引用は、ここで適切です。

送信機能が正常に完了しても、データが正常に配信され、受信者に受信されたことを示すわけではありません。この関数は、データが正常に送信されたことを示すだけです。

送信するデータを保持するためのバッファ領域がトランスポート システム内にない場合、send は、ソケットが非ブロッキング モードに設定されていない限りブロックします。

64KB (正確に 65537 から始まる) を超える書き込みを試みましたが、最初の呼び出しでブロックされました。

これは Asio の仕組みではなく、TCP とソケットの仕組みです。この答えも役立つかもしれません。

クライアントから明示的に受信確認を送信する必要があると思います。つまり、独自のアプリケーション層プロトコルをロールします。

于 2012-05-11T10:24:37.677 に答える