10 #ifndef BOOST_ASIO_HPP
11 #error "asio.hpp must be included before including this, see asiolink.h as to why"
14 #include <netinet/in.h>
15 #include <sys/socket.h>
22 #include <boost/bind.hpp>
23 #include <boost/numeric/conversion/cast.hpp>
78 #if BOOST_VERSION < 106600
79 return (socket_.native());
81 return (socket_.native_handle());
107 if (socket_.is_open()) {
109 const bool non_blocking_orig = socket_.non_blocking();
112 socket_.non_blocking(
true);
114 boost::system::error_code ec;
119 socket_.receive(boost::asio::buffer(data,
sizeof(data)),
120 boost::asio::socket_base::message_peek,
124 socket_.non_blocking(non_blocking_orig);
132 return (!ec || (ec.value() == boost::asio::error::try_again) ||
133 (ec.value() == boost::asio::error::would_block));
175 void asyncSend(
const void* data,
size_t length, C& callback);
207 size_t& cumulative,
size_t& offset,
228 boost::asio::ip::tcp::socket* socket_ptr_;
229 boost::asio::ip::tcp::socket& socket_;
249 template <
typename C>
251 socket_ptr_(NULL), socket_(socket), send_buffer_()
257 template <
typename C>
259 socket_ptr_(new
boost::asio::ip::tcp::socket(service.get_io_service())),
260 socket_(*socket_ptr_)
266 template <
typename C>
274 template <
typename C>
void
278 if (socket_.is_open() && !isUsable()) {
284 if (!socket_.is_open()) {
286 socket_.open(boost::asio::ip::tcp::v4());
289 socket_.open(boost::asio::ip::tcp::v6());
296 socket_.set_option(boost::asio::socket_base::reuse_address(
true));
316 template <
typename C>
void
319 if (socket_.is_open()) {
323 send_buffer_->writeData(data, length);
326 socket_.async_send(boost::asio::buffer(send_buffer_->getData(),
327 send_buffer_->getLength()),
329 }
catch (boost::numeric::bad_numeric_cast&) {
331 "attempt to send buffer larger than 64kB");
336 "attempt to send on a TCP socket that is not open");
340 template <
typename C>
void
344 if (socket_.is_open()) {
351 uint16_t count = boost::numeric_cast<uint16_t>(length);
355 send_buffer_->writeUint16(count);
356 send_buffer_->writeData(data, length);
359 socket_.async_send(boost::asio::buffer(send_buffer_->getData(),
360 send_buffer_->getLength()), callback);
361 }
catch (boost::numeric::bad_numeric_cast&) {
363 "attempt to send buffer larger than 64kB");
368 "attempt to send on a TCP socket that is not open");
375 template <
typename C>
void
379 if (socket_.is_open()) {
398 if (offset >= length) {
400 "TCP receive buffer");
402 void* buffer_start =
static_cast<void*
>(
static_cast<uint8_t*
>(data) + offset);
405 socket_.async_receive(boost::asio::buffer(buffer_start, length - offset), callback);
409 "attempt to receive from a TCP socket that is not open");
415 template <
typename C>
bool
417 size_t& cumulative,
size_t& offset,
422 const uint8_t* data =
static_cast<const uint8_t*
>(staging);
423 size_t data_length = length;
427 if (cumulative < 2) {
431 cumulative += length;
432 if (cumulative < 2) {
451 data_length = cumulative - 2;
455 cumulative += length;
465 if (expected >= outbuff->getLength()) {
469 size_t copy_amount = std::min(expected - outbuff->getLength(), data_length);
470 outbuff->writeData(data, copy_amount);
474 return (expected == outbuff->getLength());
479 template <
typename C>
void
481 if (socket_.is_open()) {
489 template <
typename C>
void
491 if (socket_.is_open() && socket_ptr_) {
499 #endif // TCP_SOCKET_H