logo       

Re: multiple ports on same io_service, attaching other services: msg#00038

lib.boost.asio.user

Subject: Re: multiple ports on same io_service, attaching other services

Hi Charlls,

Charlls Quarra wrote:
> it is possible to handle multiple ports on the same
> io_service? the common way would be to have a
> io_service for each port, but this demands a thread
> per port, so i was investigating a way to handle
> various connections on the same io_service, in
> particular having more than one tcp::acceptor calling
> async_accept. In my simple-minded attempt to do this (
> i attach the source of the example involved, is just
> async_tcp_echo_server slightly modified ). The example
> uses two acceptors (acceptor_A and acceptor_B). I
> found that when a second client connects after a first
> client has connected on the other port, the server
> locks up and it stop being responsive.
> What went wrong? or isn't supposed to handle multiple
> ports per io_service?

The problem with the sample program you attached is that it is using the
same session object (and therefore the same socket) with both
async_accept operations. As Richard suggested, the simplest way to do it
correctly is probably to just have two separate server objects. The
Daytime.7 tutorial program does something similar where it runs both a
UDP and TCP server on the same io_service.

> the second question is about the
> io_service::add/has_service calls; i was curious about
> how these fit in the whole machine and i wondered in
> what practical circumstances one may need to use
> these?

Sometimes a program will need to associate a single instance of a class
with an io_service object -- the sort of thing you might otherwise have
done using a singleton, but I am allergic to singletons :) Here's one
possible example:

For example:

class logger_service_base
: public io_service::service
{
public:
logger_service_base(io_service& i) : io_service::service(i) {}
virtual void log(const std::string& msg) { /* do nothing */ }
}

class syslog_logger_service
: public logger_service_base
{
public:
syslog_logger_service(io_service& i) : logger_service_base(i) {}
virtual void log(const std::string& msg) { ... }
};

class file_logger_service
: public logger_service_base
{
public:
file_logger_service(io_service& i) : logger_service_base(i) {}
virtual void log(const std::string& msg) { ... }
};

int main()
{
io_service ios;

...

if (has_service<logger_service_base>(ios))
{
// Too late, someone has already created the logger service.
}
else
{
auto_ptr<logger_service_base> logger_service;
if (use_syslog)
logger_service.reset(new syslog_logger_service(ios));
else
logger_service.reset(new file_logger_service(ios));
add_service<logger_service_base>(ios, logger_service.get());
logger_service.release();
}

...
}

Cheers,
Chris

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV


<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise