Go to the documentation of this file.00001
00008 #include "TCP.h"
00009
00010 namespace apps
00011 {
00012 using boost::asio::ip::tcp;
00013 using namespace std;
00014
00015 TCP::TCP(unsigned int port)
00016 {
00017 _choosenMode = server;
00018 _port = port;
00019
00020 _delay = 2000000;
00021
00022 _requestNewConnection = false;
00023
00024 _server = new tcp::acceptor(_ioService, tcp::endpoint(tcp::v4(), _port));
00025 _socket = NULL;
00026
00027 _timer = new boost::asio::deadline_timer(_ioService);
00028
00029 _targetServer = NULL;
00030 }
00031
00032 TCP::TCP(std::string ip, unsigned int port)
00033 {
00034 _choosenMode = client;
00035 _port = port;
00036 _ip = ip;
00037
00038 _delay = 2000000;
00039
00040 _requestNewConnection = false;
00041
00042 _targetServer = new boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string(_ip),_port);
00043 _socket = NULL;
00044
00045 _timer = new boost::asio::deadline_timer(_ioService);
00046
00047 _server = NULL;
00048 }
00049
00050 TCP::~TCP()
00051 {
00052 if(!_server) delete _server;
00053 if(!_timer) delete _timer;
00054 if(!_socket) delete _socket;
00055 if(!_targetServer) delete _targetServer;
00056 }
00057
00058 int TCP::read(void* data, unsigned int size)
00059 {
00060 int ret = -1;
00061 try{
00062 ret = _socket->read_some(boost::asio::buffer(data,size));
00063 }
00064 catch(boost::system::system_error& e)
00065 {
00066
00067 this->connectOnce();
00068 ret = -1;
00069 }
00070 return ret;
00071 }
00072
00073 int TCP::readAll(void* data, unsigned int size)
00074 {
00075 int tmp_read = 0;
00076 int ret = 0;
00077 unsigned char* tmp_data = (unsigned char*)data;
00078
00079 while(tmp_read < size)
00080 {
00081 void* tmp_data_void = (void*)&tmp_data[tmp_read];
00082 try{
00083 ret = _socket->read_some(boost::asio::buffer(tmp_data_void, size - tmp_read));
00084 tmp_read += ret;
00085 }
00086 catch(boost::system::system_error& e)
00087 {
00088 this->connectOnce();
00089 return -1;
00090 }
00091 }
00092 return 0;
00093 }
00094
00095
00096 int TCP::read(void* data, unsigned int size, unsigned int delay_us)
00097 {
00098 bool data_available = false;
00099 _socket->async_read_some(boost::asio::buffer(data,size),
00100 boost::bind(&TCP::read_callback,
00101 this,
00102 boost::ref(data_available),
00103 boost::ref(*_timer),
00104 boost::asio::placeholders::error,
00105 boost::asio::placeholders::bytes_transferred)
00106 );
00107
00108 boost::posix_time::microsec delay_boost(delay_us);
00109
00110 _timer->expires_from_now(delay_boost);
00111
00112 _timer->async_wait(boost::bind(&TCP::wait_callback,
00113 this,
00114 boost::ref(*_socket),
00115 boost::asio::placeholders::error));
00116
00117 _ioService.run();
00118
00119 _ioService.reset();
00120
00121 if(_requestNewConnection)
00122 {
00123 _requestNewConnection = false;
00124 this->connectOnce();
00125 return -1;
00126 }
00127
00128 if (!data_available)
00129 {
00130
00131
00132 return -2;
00133 }
00134 return 0;
00135 }
00136
00137
00138 int TCP::connectOnce()
00139 {
00140 if(_choosenMode == server)
00141 {
00142 delete _socket;
00143 _socket = new tcp::socket(_ioService);
00144 _server->accept(*_socket);
00145 }
00146 else if(_choosenMode == client)
00147 {
00148
00149 bool ok = true;
00150 do{
00151 try{
00152 delete _socket;
00153 _socket = new boost::asio::ip::tcp::socket(_ioService);
00154 _socket->connect(*_targetServer);
00155 ok = true;
00156 }
00157 catch(boost::system::system_error& e)
00158 {
00159 ok = false;
00160 usleep(_delay);
00161 }
00162 }while(!ok);
00163 }
00164 return 0;
00165 }
00166
00167 int TCP::write(void* data, unsigned int size)
00168 {
00169 try{
00170 _socket->write_some(boost::asio::buffer(data,size));
00171 }
00172 catch(boost::system::system_error& e)
00173 {
00174
00175 this->connectOnce();
00176 return -1;
00177 }
00178 return 0;
00179 }
00180
00181 void TCP::read_callback(bool& data_available,
00182 boost::asio::deadline_timer& timeout,
00183 const boost::system::error_code& error, std::size_t bytes_transferred)
00184 {
00185
00186
00187 if(error.value() == ERROR_CODE_LOST_SOCKET)
00188 {
00189 _requestNewConnection = true;
00190 }
00191 if (error || !bytes_transferred)
00192 {
00193
00194 data_available = false;
00195 return;
00196 }
00197
00198 timeout.cancel();
00199 data_available = true;
00200 }
00201
00202 void TCP::wait_callback(boost::asio::ip::tcp::socket& ser_port,
00203 const boost::system::error_code& error)
00204 {
00205
00206 if(error)
00207 {
00208
00209 return;
00210 }
00211
00212 ser_port.cancel();
00213 }
00214
00215 }
00216
00217