Changeset 11190


Ignore:
Timestamp:
06/27/11 13:00:22 (13 years ago)
Author:
tbretz
Message:
Added the possbility to give an IP Address with a port rather than a name which must be resolved; send keep alive packages in 10s intervals
Location:
trunk/FACT++/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/Connection.cc

    r11164 r11190  
    33
    44@brief Maintains an ansynchronous TCP/IP client connection
     5
     6@todo
     7   Unify with ConnectionUSB
    58
    69*/
     
    4447}
    4548
     49/*
    4650void Connection::AsyncWait(ba::deadline_timer &timer, int millisec,
    4751                           void (Connection::*handler)(const bs::error_code&))
     
    5963    timer.async_wait(boost::bind(handler, this, dummy::error));
    6064}
     65*/
    6166
    6267void Connection::AsyncConnect(tcp::resolver::iterator iterator)
     
    6671    // AsyncConnect + Deadline
    6772     async_connect(endpoint,
    68                   boost::bind(&Connection::ConnectImp,
    69                               this, ba::placeholders::error,
    70                               iterator));
     73                  boost::bind(&Connection::ConnectIterImp,
     74                              this, iterator, ba::placeholders::error));
     75
     76    // We will get a "Connection timeout anyway"
     77    //AsyncWait(fConnectTimeout, 5, &Connection::HandleConnectTimeout);
     78}
     79
     80void Connection::AsyncConnect()
     81{
     82    // AsyncConnect + Deadline
     83     async_connect(fEndpoint,
     84                  boost::bind(&Connection::ConnectAddrImp,
     85                              this, fEndpoint, ba::placeholders::error));
    7186
    7287    // We will get a "Connection timeout anyway"
     
    275290}
    276291
    277 void Connection::ConnectImp(const bs::error_code& error,
    278                             tcp::resolver::iterator iterator)
    279 {
    280     tcp::endpoint endpoint = *iterator;
    281 
     292void Connection::ConnectAddrImp(const tcp::endpoint &endpoint, const bs::error_code& error)
     293{
    282294    const string host = endpoint.port()==0 ? "" :
    283295        endpoint.address().to_string()+":"+lexical_cast<string>(endpoint.port());
     
    325337
    326338    fConnectionStatus = kConnecting;
    327 
     339/*
    328340    // Go on with the next
    329341    if (++iterator != tcp::resolver::iterator())
     
    332344        return;
    333345    }
    334 
     346*/
    335347    // No more entries to try, if we would not put anything else
    336348    // into the queue anymore it would now return (run() would return)
     
    343355}
    344356
     357void Connection::ConnectIterImp(tcp::resolver::iterator iterator, const bs::error_code& error)
     358{
     359    ConnectAddrImp(*iterator, error);
     360/*
     361    tcp::endpoint endpoint = *iterator;
     362
     363    const string host = endpoint.port()==0 ? "" :
     364        endpoint.address().to_string()+":"+lexical_cast<string>(endpoint.port());
     365
     366    // Connection established
     367    if (!error)
     368    {
     369        set_option(socket_base::keep_alive(true));
     370
     371        const int optval = 10;
     372        // First keep alive after 10s
     373        setsockopt(native(), SOL_TCP, TCP_KEEPIDLE, &optval, sizeof(optval));
     374        // New keep alive after 10s
     375        setsockopt(native(), SOL_TCP, TCP_KEEPINTVL, &optval, sizeof(optval));
     376
     377        Info("Connection established to "+host+"...");
     378
     379        fConnectionStatus = kConnected;
     380
     381        ConnectionEstablished();
     382        return;
     383    }
     384
     385    // If returning from run will lead to deletion of this
     386    // instance, close() is not needed (maybe implicitly called).
     387    // If run is called again, close() is needed here. Otherwise:
     388    // Software caused connection abort when we try to resolve
     389    // the endpoint again.
     390    CloseImp(false);
     391
     392    ostringstream msg;
     393    if (!host.empty())
     394        msg << "Connecting to " << host << ": " << error.message() << " (" << error << ")";
     395
     396    if (fErrConnect!=msg.str())
     397    {
     398        if (error!=ba::error::basic_errors::connection_refused)
     399            fMsgConnect = "";
     400        fErrConnect = msg.str();
     401        Warn(fErrConnect);
     402    }
     403
     404    if (error==ba::error::basic_errors::operation_aborted)
     405        return;
     406
     407    fConnectionStatus = kConnecting;
     408*/
     409    // Go on with the next
     410    if (++iterator != tcp::resolver::iterator())
     411    {
     412        AsyncConnect(iterator);
     413        return;
     414    }
     415/*
     416    // No more entries to try, if we would not put anything else
     417    // into the queue anymore it would now return (run() would return)
     418
     419    // Since we don't want to block the main loop, we wait using an
     420    // asnychronous timer
     421
     422    // FIXME: Should we move this before AsyncConnect() ?
     423    AsyncWait(fConnectionTimer, 250, &Connection::HandleConnectionTimer);
     424*/
     425}
     426
    345427// FIXME: Async connect should get address and port as an argument
    346428void Connection::StartConnect()
    347429{
    348430    fConnectionStatus = kConnecting;
     431
     432    if (fEndpoint!=tcp::endpoint())
     433    {
     434        ostringstream msg;
     435        msg << "Trying to connect to " << fEndpoint << "...";
     436        Info(msg);
     437
     438        AsyncConnect();
     439        return;
     440    }
    349441
    350442    tcp::resolver resolver(get_io_service());
  • trunk/FACT++/src/Connection.h

    r11118 r11190  
    44#include <deque>
    55#include <string>
     6#include <boost/bind.hpp>
    67#include <boost/asio.hpp>
    78#include <boost/function.hpp>
     
    1718    std::string fAddress;
    1819    std::string fPort;
     20
     21    boost::asio::ip::tcp::endpoint fEndpoint;
    1922
    2023    bool fDebugTx;
     
    4851    void AsyncRead(const boost::asio::mutable_buffers_1 buffers, int type=0);
    4952    void AsyncWrite(const boost::asio::const_buffers_1 &buffers);
     53
     54    template<class T>
     55    void AsyncWaitImp(boost::asio::deadline_timer &timer, int millisec,
     56                      void (T::*handler)(const boost::system::error_code&))
     57    {
     58        // - The boost::asio::basic_deadline_timer::expires_from_now()
     59        //   function cancels any pending asynchronous waits, and returns
     60        //   the number of asynchronous waits that were cancelled. If it
     61        //   returns 0 then you were too late and the wait handler has
     62        //   already been executed, or will soon be executed. If it
     63        //   returns 1 then the wait handler was successfully cancelled.
     64        // - If a wait handler is cancelled, the bs::error_code passed to
     65        //   it contains the value bs::error::operation_aborted.
     66        timer.expires_from_now(boost::posix_time::milliseconds(millisec));
     67
     68        timer.async_wait(boost::bind(handler, this, boost::asio::placeholders::error));
     69    }
     70
    5071    void AsyncWait(boost::asio::deadline_timer &timer, int millisec,
    51                    void (Connection::*handler)(const boost::system::error_code&));
     72                   void (Connection::*handler)(const boost::system::error_code&))
     73    {
     74        AsyncWaitImp(timer, millisec, handler);
     75    }
     76
    5277
    5378private:
    5479    void AsyncConnect(boost::asio::ip::tcp::resolver::iterator iterator);
     80    void AsyncConnect();
    5581
    5682    void CloseImp(bool restart=true);
    5783
    58     void ConnectImp(const boost::system::error_code& error,
    59                     boost::asio::ip::tcp::resolver::iterator endpoint_iterator);
     84    void ConnectAddrImp(const boost::asio::ip::tcp::endpoint &endpoint,
     85                        const boost::system::error_code& error);
     86    void ConnectIterImp(boost::asio::ip::tcp::resolver::iterator endpoint_iterator,
     87                        const boost::system::error_code& error);
    6088
    6189    void HandleConnectionTimer(const boost::system::error_code &error);
     
    75103    void SetEndpoint(const std::string &addr, const std::string &port);
    76104    void SetEndpoint(const std::string &addr);
     105    void SetEndpoint(const boost::asio::ip::tcp::endpoint &ep) { fEndpoint = ep; }
    77106
    78107    void StartConnect();
     
    112141
    113142    std::string URL() const { return fAddress + ":" + fPort; }
     143
     144    const boost::asio::ip::tcp::endpoint &GetEndpoint() const { return fEndpoint; }
    114145};
    115146
Note: See TracChangeset for help on using the changeset viewer.