TCP.cpp
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)             //server
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)             //client
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             //get new connection
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();  // will block until async callbacks are finished
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         //no data;
00131         //std::cout << "debug: receive timed out or failed" << std::endl;
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);  //wait for connection....
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         //get new connection
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     //std::cout << "debug: called -> read_callback(...):->" << error.value() << "<-" << std::endl;
00187     if(error.value() == ERROR_CODE_LOST_SOCKET)
00188     {
00189         _requestNewConnection = true;
00190     }
00191     if (error || !bytes_transferred)
00192     {
00193         // No data was read!
00194         data_available = false;
00195         return;
00196     }
00197 
00198     timeout.cancel();  // will cause wait_callback to fire with an error
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     //std::cout << "debug: called -> SerialCom::wait_callback(...)" << std::endl;
00206     if(error)
00207     {
00208         // Data was read and this timeout was canceled
00209         return;
00210     }
00211 
00212     ser_port.cancel();  // will cause read_callback to fire with an error
00213 }
00214 
00215 } /* namespace apps */
00216 
00217 


vrmagic_ros_bridge_server
Author(s): Michael Schmidpeter
autogenerated on Thu Aug 27 2015 15:40:39