2009-08-10 30 views
0

私はasioを使用する際に問題があります。私のクライアント/サーバーアプリケーションは、同期通信だけを必要とします。したがって、ブーストホームページのシンクロの例を使用して、データを送受信する手順を2つ設定しました。コードは次のとおりです。ブースト.Asio同期通信

これらの手順は、ブーストの例から抽出されたコード行のラッパーです。私のテストアプリケーションで

、クライアントは

std::string szDate; 
vReceive(socket, szDate); 
vSend(socket, std::string("Chop Suey!")); 
vReceive(socket, szDate); 
vSend(socket, std::string("Halo")); 

を呼び出し、サーバーだけで機能をテストするために

std::string message = make_daytime_string(); 
std::string szReceived; 
vSend(socket, message); 
vReceive(socket, szReceived); 
vSend(socket, message); 
vReceive(socket, szReceived); 

を呼び出します。問題は、私が次のように書いたように、最初の情報交換後に両方のアプリケーションがフリーズすることです。picture vSend()がサーバ側で終了している間に、クライアント側で vReceive()プロシージャが終了していないようです。だから誰にも何のアイデアはありますか?何が間違っているのでしょうか?

誰かが問題を再現したい場合は、完全なソースをasio_problem.rarファイルにある同じサーバーにアップロードしました(新しいメンバーとして1つのハイパーリンクを持つことができます)。

ありがとうございました。 ダニエル

答えて

1

私はあなたの問題はここにあると思う:

for (;;){ 
    /* snipped */ 

    if (error == boost::asio::error::eof) 
    break; // Connection closed cleanly by peer. 
    else if (error) 
    throw boost::system::system_error(error); // Some other error. 

    /* snipped */ 
} 

あなたは、接続が閉じます(ソケットからEOFエラーが表示された場合はループから抜け出すための唯一の方法である)まで無限ループが、vSendされていますソケットを決して閉じません。つまり、クライアントのvReceiveは永遠に待っていて、常により多くのデータを待っています。 vSendsocket.close()を入れるとうまくやってみるべきです。もちろん

が、これはあなたのクライアントとサーバーがvReceivevSendへのそれぞれの呼び出しの後にソケットを再オープンする必要があることを意味します。それが望ましくない場合は、受信者にそれ以上データが送信されないことを通知する送信者の他の手段を使用することをお勧めします。

ワイヤで送信されるデータに制約がありますが、メッセージの先頭に「データ長」の値を送信するか、何らかの「データの終わり」のセンチネル値を指定すると、より多くのデータを受信するのを止めるきっかけとなる優れた指標が得られます。

このアプローチには、ASIOのread_until(または類似の)機能を使用して、データの終了を待つロジックを処理する理由が追加されています。

関連する問題