James Flemer
2014-01-17 22:19:30 UTC
I am curious if anyone has implemented anything within the ASIO framework
to handle a tcp socket like it was datagram socket. Many protocols
implemented on TCP are really a sequence of discrete messages. The chat
example in the ASIO docs is a perfect example, the tcp stream is always a
header saying how long the payload is followed by the payload itself. In
the "chat_session" object, the action for receiving a message is hard coded
into the handle_read_body() method (i.e. calling room_.deliver).
The design I am envisioning would be used something like this instead (very
brief, but hopefully enough to demonstrate the idea):
chat::socket chat(io_service); // the chat io object, like
asio::ip::udp::socket
chat::room room;
chat::message msg; // or could be a "MutableBufferSequence"
chat.async_receive(msg, boost::bind(&chat::room::deliver, &room, _1));
So rather than chat working "on top" of ASIO, we extend ASIO to support the
"chat socket" as an extension of ASIO.
I think this could be "faked" by making chat::socket a "thick"
implementation that simply wraps multiple use of asio::ip::tcp similar to
how the current chat example is written. I believe this would require
handler storage or "chaining", where the handler used for the tcp socket
async_receive() was given the handler passed into
chat::scocket::async_receive(). But this doesn't really seem to be the
ASIO way.
I think, the "right" way would be to go ahead and implement a new service
as well that actually ended up using io_service::post to invoke the handler
given to chat::async_receive().
Has this been done? Does it sound like it would be a good idea to do? I
think it could be generalized for the class of protocols with fixed length
headers, and probably for the class of delimited header/body protocols as
well. Then chat would be something like:
struct chat {
typedef basic_fixed_header_message_socket<chat, ip::tcp> socket;
static const size_t header_size = 128;
// plus something to get payload size after receipt of header
}
Such a template (or set of templates) could really cut down on the
repetitive receive header, receive payload cyclic dance that chat so
clearly demonstrates.
-James
to handle a tcp socket like it was datagram socket. Many protocols
implemented on TCP are really a sequence of discrete messages. The chat
example in the ASIO docs is a perfect example, the tcp stream is always a
header saying how long the payload is followed by the payload itself. In
the "chat_session" object, the action for receiving a message is hard coded
into the handle_read_body() method (i.e. calling room_.deliver).
The design I am envisioning would be used something like this instead (very
brief, but hopefully enough to demonstrate the idea):
chat::socket chat(io_service); // the chat io object, like
asio::ip::udp::socket
chat::room room;
chat::message msg; // or could be a "MutableBufferSequence"
chat.async_receive(msg, boost::bind(&chat::room::deliver, &room, _1));
So rather than chat working "on top" of ASIO, we extend ASIO to support the
"chat socket" as an extension of ASIO.
I think this could be "faked" by making chat::socket a "thick"
implementation that simply wraps multiple use of asio::ip::tcp similar to
how the current chat example is written. I believe this would require
handler storage or "chaining", where the handler used for the tcp socket
async_receive() was given the handler passed into
chat::scocket::async_receive(). But this doesn't really seem to be the
ASIO way.
I think, the "right" way would be to go ahead and implement a new service
as well that actually ended up using io_service::post to invoke the handler
given to chat::async_receive().
Has this been done? Does it sound like it would be a good idea to do? I
think it could be generalized for the class of protocols with fixed length
headers, and probably for the class of delimited header/body protocols as
well. Then chat would be something like:
struct chat {
typedef basic_fixed_header_message_socket<chat, ip::tcp> socket;
static const size_t header_size = 128;
// plus something to get payload size after receipt of header
}
Such a template (or set of templates) could really cut down on the
repetitive receive header, receive payload cyclic dance that chat so
clearly demonstrates.
-James