2016-04-19 11 views
0

をソケットを渡すには:ブースト:: ASIO - 私は現在、以下のアプリケーションが動作するように取得しようとしています第二のクラスに

  1. は、着信クライアント接続を待ちます。
  2. 非同期を開始します。他のクラスのタイマー。
  3. タイマーが繰り返し実行されている間に、async_readasync_writeなどの他のものを実行します。

現在のソースコード

#define BOOST_ASIO_ENABLE_HANDLER_TRACKING 

#include <WinSock2.h> 
#include <Mswsock.h> 
#include <boost/asio.hpp> 
#include <boost/bind.hpp> 
#include "TimerClass.hpp" 

using namespace boost::asio; 
using namespace boost::asio::ip; 

TimerClass *timerClass; 

void acceptHandler(const boost::system::error_code &errorCode, tcp::socket *socket) { 
    timerClass = new TimerClass(socket); 
    timerClass->startTimer(); 
    while(true) { 
     // Do other suff such as async_write, ... 
    } 
} 

int main(int argc, char** argv) { 
    io_service ioService; 
    tcp::socket socket(ioService); 
    tcp::acceptor acceptor{ ioService, tcp::endpoint{ tcp::v4(), 12345 } }; 
    acceptor.listen(); 
    acceptor.async_accept(socket, boost::bind(acceptHandler, _1, &socket)); 
    ioService.run(); 
    return EXIT_SUCCESS; 
} 

TimerClass.hpp

#include <boost/asio.hpp> 
#include <boost/date_time/posix_time/posix_time.hpp> 

using namespace boost::asio; 
using namespace boost::posix_time; 

class TimerClass { 
public: 
    TimerClass(ip::tcp::socket *socket); 
    void startTimer(); 
    void timerHandler(const boost::system::error_code& errorCode); 
    deadline_timer timer; 
}; 

TimerClass.cpp

#include <boost/bind.hpp> 
#include "TimerClass.hpp" 

TimerClass::TimerClass(ip::tcp::socket *socket) : timer(socket->get_io_service(), boost::posix_time::seconds(1)) {} 

void TimerClass::startTimer() { 
    timer.async_wait(boost::bind(&TimerClass::timerHandler, this, boost::asio::placeholders::error)); 
} 

void TimerClass::timerHandler(const boost::system::error_code& errorCode) { 
    timer.expires_at(timer.expires_at() + boost::posix_time::seconds(1)); 
    timer.async_wait(boost::bind(&TimerClass::timerHandler, this, boost::asio::placeholders::error)); 
} 

ハンドラのトラッキング出力

@asio|1461070492.111630|0*1|[email protected]_accept 
@asio|1461070498.527997|>1|ec=system:0 

質問

  1. なぜそれがさらにstartTimerasync_waitを呼び出すことではないでしょうか?デバッグではstartTimerが呼び出されますが、Handler Trackingの出力では何も見つかりません。何故ですか?
  2. ソケットをTimerClassに正しく渡していますか?
  3. acceptHandlerでwhile(true)ループを無制限に実行しないと、acceptHandlerは返しますが、io_serviceが正しく返される前にアプリケーションがクラッシュします。それはどうですか?
+0

コードをコンパイルしましたが、実際には 'async_wait'の呼び出しがあります。どのブーストバージョンを使用していますか(1.54で試しました)。ハンドラのトラッキング出力: '@asio | 1461081908.437388 | 0 * 1 | [email protected]_accept @asio | 1461081983.220840 |> 1 | EC =システム:0 @asio | 1461081983.221817 | 1 * 2 | deadline_timer @ 001C1318.async_wait' – Nacho

+0

@ Nachoバージョン1.59.0を使用しています - あなたの実行でタイマーが実際に動作しますか?毎秒実行する必要があります。 – chrisp

+0

実際には、私は 'while(true)'を削除しなければなりませんでした。ああ、私は何が問題だろうか知っています。 'TimerClass.hpp'にガードを含んでいますか? – Nacho

答えて

2

私はあなたのコードをコンパイルしました。私のために(ブーストバージョン1.54を使用して)動作します。あなたのコードで

私は次のような出力が得られます。

@asio|1461081908.437388|0*1|[email protected]_accept 
@asio|1461081983.220840|>1|ec=system:0  
@asio|1461081983.221817|1*2|[email protected]_wait 

それは私には、次の出力を得る、あなたのacceptHandlerwhile(true)を削除する必要がありました正しく実行させるには(ハンドラ内std::coutを追加しました):

@asio|1461083707.104424|0*1|[email protected]_accept 
@asio|1461083709.061824|>1|ec=system:0 
@asio|1461083709.062803|1*2|[email protected]_wait 
@asio|1461083709.062803|<28158494073611763| 
@asio|1461083710.064992|>2|ec=system:0 
@asio|1461083710.064992|2|[email protected] 
@asio|1461083710.064992|2*3|[email protected]_wait 
TimerHandler executed... 
@asio|1461083710.065971|<28169626628843099| 
@asio|1461083711.065223|>3|ec=system:0 
@asio|1461083711.065223|3|[email protected] 
@asio|1461083711.065223|3*4|[email protected]18.async_wait 
TimerHandler executed... 

私は実際にこのテストをヘッダーTimerClass.hpp(直接的にメソッドを定義しています - 私は怠惰でした)だけを使って行いましたが、それは魅力的でした。問題は使用時のようです.cppファイルです。そのため、あなたがインクルードガードを使用していたかどうかを尋ねました(問題はありませんが、既にテスト済みです)。


あなたはすなわち、(async_readまたはasync_writeのように)必要であれば、ちょうど別の非同期操作を呼び出す、あなたのハンドラでは、ブロッキングループを使用していない、しかし、あなたの設計アプローチを変更することを検討すべきです。

this questionをご覧ください。それに対応した回答は、素晴らしいサーバー実装のアイデアです。または、お客様のニーズに合わせてboost examplesの一部を修正してみてください。

対応するヘッダーファイルと実装ファイルで定義から宣言を分離する際に発生するセグメンテーションフォールトにつきましては、this other questionにチェックを入れたい場合があります。

+0

.cppで動作しない理由はありますか?私は、むしろ.hppファイルを排他的に使用しないでください。 – chrisp

+1

@chrispはい、ソケットポインタに問題があります。 'socket *'を 'TimerClass'に渡す必要はなく、io_serviceだけが必要です。しかし、私はまだあなたの全体のインプリメントを変更することなく、幻想的な方法でコードを修正しようとしています。私に数分を与えてください – Nacho

+0

ええと、私はソケットポインタ、ソケット参照、io_serviceポインタ、io_service参照を使って試しました...何も動作していないようです。また、whileループの何が問題になっていますか?タイマーは非同期です。イベント。なぜ私はそれが動作するためにループを削除する必要がありますか?私は自分のアプリケーションで他のイベントを処理する必要があります。私はちょうどあなたの解決を待つだろうと思う。 – chrisp

関連する問題