Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <network_interface.h>
00009
00010 using namespace AS::Network;
00011 using boost::asio::ip::tcp;
00012
00013
00014 TCPInterface::TCPInterface() :
00015 socket_(io_service_)
00016 {
00017 }
00018
00019
00020 TCPInterface::~TCPInterface()
00021 {
00022 }
00023
00024 return_statuses TCPInterface::open(const char *ip_address, const int &port)
00025 {
00026 if (socket_.is_open())
00027 return OK;
00028
00029 std::stringstream sPort;
00030 sPort << port;
00031 tcp::resolver res(io_service_);
00032 tcp::resolver::query query(tcp::v4(), ip_address, sPort.str());
00033 tcp::resolver::iterator it = res.resolve(query);
00034 boost::system::error_code ec;
00035
00036 socket_.connect(*it, ec);
00037
00038 if (ec.value() == boost::system::errc::success)
00039 {
00040 return OK;
00041 }
00042 else if (ec.value() == boost::asio::error::invalid_argument)
00043 {
00044 return BAD_PARAM;
00045 }
00046 else
00047 {
00048 close();
00049 return INIT_FAILED;
00050 }
00051 }
00052
00053 return_statuses TCPInterface::close()
00054 {
00055 if (!socket_.is_open())
00056 return OK;
00057
00058 boost::system::error_code ec;
00059 socket_.close(ec);
00060
00061 if (ec.value() == boost::system::errc::success)
00062 {
00063 return OK;
00064 }
00065 else
00066 {
00067 return CLOSE_FAILED;
00068 }
00069 }
00070
00071 bool TCPInterface::is_open()
00072 {
00073 return socket_.is_open();
00074 }
00075
00076 void TCPInterface::timeout_handler(const boost::system::error_code& error)
00077 {
00078
00079 if (error != boost::asio::error::operation_aborted)
00080 {
00081 error_.assign(boost::system::errc::timed_out, boost::system::system_category());
00082 }
00083 }
00084
00085 void TCPInterface::read_handler(const boost::system::error_code& error, size_t bytes_read)
00086 {
00087 bytes_read_ = bytes_read;
00088 }
00089
00090 return_statuses TCPInterface::read(unsigned char *msg,
00091 const size_t &buf_size,
00092 size_t &bytes_read,
00093 int timeout_ms)
00094 {
00095 if (!socket_.is_open())
00096 return SOCKET_CLOSED;
00097
00098 error_.assign(boost::system::errc::success, boost::system::system_category());
00099
00100 boost::asio::deadline_timer timer(io_service_);
00101
00102 if (timeout_ms > 0)
00103 {
00104 timer.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
00105 timer.async_wait(boost::bind(&TCPInterface::timeout_handler,
00106 this,
00107 boost::asio::placeholders::error));
00108 }
00109
00110 boost::asio::async_read(socket_,
00111 boost::asio::buffer(msg, buf_size),
00112 boost::bind(&TCPInterface::read_handler,
00113 this,
00114 boost::asio::placeholders::error,
00115 boost::asio::placeholders::bytes_transferred));
00116
00117 while (io_service_.run_one())
00118 {
00119 if (error_.value() == boost::system::errc::success)
00120 {
00121 timer.cancel();
00122 bytes_read = bytes_read_;
00123 }
00124 else if (error_.value() == boost::system::errc::timed_out)
00125 {
00126 socket_.cancel();
00127 }
00128 }
00129
00130 io_service_.reset();
00131
00132 if (error_.value() == boost::system::errc::success)
00133 {
00134 return OK;
00135 }
00136 else if (error_.value() == boost::system::errc::timed_out)
00137 {
00138 return SOCKET_TIMEOUT;
00139 }
00140 else
00141 {
00142 return READ_FAILED;
00143 }
00144 }
00145
00146 return_statuses TCPInterface::read_exactly(unsigned char *msg,
00147 const size_t &buf_size,
00148 const size_t &bytes_to_read,
00149 int timeout_ms)
00150 {
00151 if (!socket_.is_open())
00152 return SOCKET_CLOSED;
00153
00154 error_.assign(boost::system::errc::success, boost::system::system_category());
00155
00156 boost::asio::deadline_timer timer(io_service_);
00157
00158 if (timeout_ms > 0)
00159 {
00160 timer.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
00161 timer.async_wait(boost::bind(&TCPInterface::timeout_handler,
00162 this,
00163 boost::asio::placeholders::error));
00164 }
00165
00166 boost::asio::async_read(socket_,
00167 boost::asio::buffer(msg, buf_size),
00168 boost::asio::transfer_exactly(bytes_to_read),
00169 boost::bind(&TCPInterface::read_handler,
00170 this,
00171 boost::asio::placeholders::error,
00172 boost::asio::placeholders::bytes_transferred));
00173
00174 while (io_service_.run_one())
00175 {
00176 if (error_.value() == boost::system::errc::success)
00177 {
00178 timer.cancel();
00179 }
00180 else if (error_.value() == boost::system::errc::timed_out)
00181 {
00182 socket_.cancel();
00183 }
00184 }
00185
00186 io_service_.reset();
00187
00188 if (error_.value() == boost::system::errc::success)
00189 {
00190 return OK;
00191 }
00192 else if (error_.value() == boost::system::errc::timed_out)
00193 {
00194 return SOCKET_TIMEOUT;
00195 }
00196 else
00197 {
00198 return READ_FAILED;
00199 }
00200 }
00201
00202 return_statuses TCPInterface::write(unsigned char *msg, const size_t &msg_size)
00203 {
00204 if (!socket_.is_open())
00205 return SOCKET_CLOSED;
00206
00207 boost::system::error_code ec;
00208 boost::asio::write(socket_, boost::asio::buffer(msg, msg_size), ec);
00209
00210 if (ec.value() == boost::system::errc::success)
00211 {
00212 return OK;
00213 }
00214 else
00215 {
00216 return WRITE_FAILED;
00217 }
00218 }