2012-05-11 27 views
3

私はboost :: asioを試していて、ブロッキングエコーの例をテストしました。彼らは完全にそれをブロックしているようには思われません。少なくとも私が期待した方法ではありません。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); 
+0

なぜデータを送信し、相手側で受信するまで待つのですか? –

+0

受信者プログラムが実際にデータを取得して処理しているかどうかは気にしないとします。 TCPプロトコルが私に何を提供しているのかだけを知りたい。だから私はasioの 'send'/'write'ブロックが 'recv'と呼ばれるレシーバーまで期待していた。 asioがそれをシーンの後ろで違って処理するなら、それは大丈夫です。私はただ好奇心が強い。 – Ivarpoiss

答えて

4

私は、基礎となるバッファがいっぱいになった場合にのみ、この場合にはwrite実際にブロックを考えます。

msdnからのこの引用は、ここで適切であろう:

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

転送するデータを保持するために転送システム内にバッファスペースがない場合、ソケットは非ブロックモードになっていなければブロックされます。

(65537で始まる)64KBを超える書き込みを試み、最初の呼び出しでブロックしました。

これはAsioの仕組みではなく、TCPとソケットの仕組みです。このanswerも助けになるかもしれません。

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

関連する問題