问题
I am to implement a (hopefully) robust asynchronious serial rs232 data transmission (via USB) - for both windows and linux, including esp. that nice embedded system called beagle bone black.
In the end I just want to be able to (compatibly) talk rs232 with robust deadline-timeouts, cancel() reset() etc. to not crash/hang when e.g. the tx or rx line disconnects accidently. So sure, I could simply copy/paste/adopt existing examples. But I also would like to become more enlightened ;-)
I decided to use boost:asio::serial_port. Now while reading the docs, I am confused about this two classes (well three with the typedef serial_port):
serial_port_service - Default service implementation for a serial port.
class serial_port_service : public io_service::service
basic_serial_port - Provides serial port functionality.
template< typename SerialPortService = serial_port_service>
class basic_serial_port :
public basic_io_object< SerialPortService >,
public serial_port_base
So faar I see, that I need a boost::asio::io_service
to construct either boost::asio::serial_port
or serial_port_service
.
I think I have understand the basic approach how asio does the job, like bespoken in e.g. this examples .
OK serial_port_service
derives from io_service, its ctor takes an io_service
, and its interface also offers those memberfuncs of basic_serial_port
.
For me it looks like it's a io_service that also implements a basic_serial_port - what is the reason for having both classes? When to use the one when the other? Not sure about possible usecases, and what about this serial_port
typedef. Maybe (well obviously) I am missing something - someone can give me more light?
回答1:
Often, the application should use the I/O object. In this case, that would be boost::asio::serial_port.
The various classes are used to separate responsibilities and abstractions. The similarity in names can be confusing, so the documentation is very careful in its naming. The documentation states:
Class
io_service
implements an extensible, type-safe, polymorphic set of I/O services, indexed by service type. An object of classio_service
must be initialised before I/O objects such as sockets, resolvers and timers can be used. These I/O objects are distinguished by having constructors that accept anio_service&
parameter.I/O services exist to manage the logical interface to the operating system on behalf of the I/O objects. In particular, there are resources that are shared across a class of I/O objects. For example, timers may be implemented in terms of a single timer queue. The I/O services manage these shared resources.
To explain this in context of serial ports:
- The io_service provides an event processing loop and manages I/O services, such as serial_port_service.
- The serial_port is an I/O object that provides an interface to perform serial port related operations. The implementation is very basic:
- Determines how information is to be returned to the caller: throw if an error occurs, populate a std::future, suspend a coroutine, etc.
- Defers the actual work to the
serial_port_service
, its I/O service. - Provides RAII semantics. When the
serial_port
is destroyed, it will cancel outstanding asynchronous operations and close theserial_port
.
- The
serial_port_service
is an I/O service:- It provides an abstraction and implements the platform specific API.
- It is shared amongst
serial_port
s that use the sameio_service
. When theserial_port
is created with anio_service
, theserial_port
will use an existingserial_port_service
registered to theio_service
or create and register a newserial_port_service
with theio_service
. - It functions as an factory for an I/O object's implementation. For a
serial_port
, this is likely a basic file descriptor or handle.
来源:https://stackoverflow.com/questions/26562965/what-is-the-difference-of-boost-asio-serial-port-service-and-serial-port