2017-03-01 17 views
1

私はboost asioでソケットプログラミングに問題があります。boost asio async_read delay(ローカルソケット)

私のプログラムの流れは以下の通りです:サーバーにデータを送信するために

クライアントの利用async_write、それがサーバーからデータを受信するためにasync_readを使用します。非同期操作のハンドラはすべてuse_futureであり、タイムアウトは2秒です。

問題があります。サーバーの

処理時間は約10ミリ秒です。サーバーとクライアントの両方が同じコンピューターにあるため、サーバーはサーバーがデータを送信している間にクライアントにデータを受け取る必要があります。しかし、私はasync_readのレイテンシを測定しました。そのうちのいくつかは約10ミリ秒で、他は約30〜40ミリ秒でした。通常、それらはインターリーブされます。

はどのようにして測定を実行します。

  1. を後押しする:: ASIO ::ストリームバッファを大きなスペースを割り当て:

    auto start_time = std::chrono::steady_clock::now(); 
    
    auto read_result = async_read(..., use_future); 
    auto read_future_status = read_result.wait_for(timeout); 
    
    auto end_time = std::chrono::steady_clock::now(); 
    

    私は2つのソリューションを試してみました。私は4096バイトを割り当て、データサイズは1500バイトを超えることはありませんが、動作しません。

  2. socket_.set_option(ip::tcp::no_delay(true));を使用すると、Nagle's AlgorithmとDelay Ackがオフになります。また、動作しません。

私はこの問題について考えていません。誰でも私を助けることができますか?してください...

アップデート:ここに私のソースコードの下

の部分があるサーバへの送信要求のコードです:

以下
auto send_result = async_write(input_socket, out_buffer, use_future); 
auto send_status = send_result.wait_for(std::chrono::seconds(timeout)); 
if(send_status == std::future_status::timeout) 
{ 
    LOG4CPLUS_ERROR_FMT(logger_, "send %s future error : (%d).", action, send_status); 
} 

out_buffer.consume(request.length()); 

は、サーバからデータを受信するコードです。

auto read_buffer_result = async_read(output_socket, in_buffer, transfer_exactly(sizeof(Header)), use_future); 
auto read_status = read_buffer_result.wait_for(std::chrono::seconds(timeout)); 
if(read_status == std::future_status::timeout) 
{ 
    LOG4CPLUS_ERROR_FMT(logger_, "read %s header future error : (%d).", action, read_status); 
} 
size_t byte_transferred = read_buffer_result.get(); 
in_buffer.consume(byte_transferred); 
+2

コード –

+2

...またはさらに完全な(短い!)例 –

+0

を返信いただきありがとうございます。私はソースコードを投稿しようとします。 – CenaWang

答えて

1

私が最初に推測したことは、完全な入出力が完了するまでASIOをブロックすることです。それは待ち時間をもたらす。

遅延の影響を受けやすいコードの場合は、常にasync_read_some()async_write_some()を使用する必要があります。これらは、できるだけ早くOSが行うことができるように、できるだけ早く部分I/Oを返します。部分的なI/Oを処理するコードをリファクタリングする必要があります。基本的には、ハンドラの呼び出しごとに処理し、バッファされていない部分的に送信または受信されたバッファのバッファシーケンスを、次回の再試行時に使用します。

2番目の推測では、ストランドを使用している可能性があります。これらはレイテンシを導入する。 asio-usersメーリングリストを参照してください。

1

ありがとうございます。私は答えを見つけました---私は実行するためにデバッグバージョンを使用します... しかし、何かはまだ変わっています。

まず、私はデバッグモードで開発します。開発が完了したら、私はリリースモードに切り替え、 "Build Solution"を使用して自分のDLLを構築します。私はdllがリリース版だと思ったので、パフォーマンスを評価し始めました。しかし今朝、私は "Clean Solution"を使い、その後 "Build Solution"を使うつもりはありません。ビルの後、パフォーマンスを再び評価したところ、ほぼすべてのレイテンシが10ミリ秒になったことがわかりました。今朝までの評価は、デバッグ版のdllで行っていると思います。

"デバッグからリリースへの切り替えとソリューションのビルド"と "デバッグからリリースへの切り替えとソリューションのクリーンアップとソリューションのビルド"の違いはまだ分かりません。

私はその違いを見つけようとします。

本当に助けていただきありがとうございます。

関連する問題