Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <cstdio>
00028 #include <sys/socket.h>
00029 #include <fcntl.h>
00030 #include <errno.h>
00031 #include <rtt/Logger.hpp>
00032 #include <string.h>
00033 #include "socket.hpp"
00034
00035 using RTT::Logger;
00036
00037 #define MSGLENGTH 100
00038 #if MSGLENGTH * 3 > BUFLENGTH
00039 #error "MSGLENGTH too long"
00040 #endif
00041
00042 #if __APPLE__
00043 #define SEND_OPTIONS 0
00044 #else
00045 #define SEND_OPTIONS MSG_NOSIGNAL
00046 #endif
00047
00048 namespace {
00049 const unsigned int bufsize = 2048;
00050 class sockbuf : public std::streambuf
00051 {
00052 private:
00053 char* ptr;
00054 OCL::TCP::Socket* mainClass;
00055
00056 public:
00057 sockbuf( OCL::TCP::Socket* m ) : mainClass(m)
00058 {
00059 char* ptr = new char[bufsize];
00060 setp(ptr, ptr + bufsize);
00061 setg(0, 0, 0);
00062 #if __APPLE__
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 int value = 1;
00073 if (-1 == setsockopt(
00074 mainClass->socket, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value)))
00075 {
00076 Logger::log() << Logger::Error << "Error setting socket option. Continuing." << Logger::endl;
00077 }
00078 #endif
00079 }
00080
00081 ~sockbuf()
00082 {
00083 sync();
00084 delete[] ptr;
00085 }
00086
00087 int overflow(int c)
00088 {
00089 int ret = 0;
00090 put_buffer();
00091
00092 if (c != EOF)
00093 {
00094 if (pbase() == epptr())
00095 {
00096 put_char(c);
00097 } else {
00098 ret = sputc(c);
00099 }
00100 } else {
00101 ret = EOF;
00102 }
00103 return ret;
00104 }
00105
00106 int sync()
00107 {
00108 put_buffer();
00109 return 0;
00110 }
00111
00112 void put_char(int chr)
00113 {
00114 Logger::log() << Logger::Error << "Socket::put_char is unimplemented" << Logger::endl;
00115 }
00116
00117 void put_buffer()
00118 {
00119 if (pbase() != pptr())
00120 {
00121 int length = (pptr() - pbase());
00122 char *buffer = new char[length + 1];
00123
00124 strncpy(buffer, pbase(), length);
00125 buffer[length] = '\0';
00126
00127
00128 if( length && ::send ( mainClass->socket, buffer, length, SEND_OPTIONS ) == -1 )
00129 {
00130 mainClass->rawClose();
00131 }
00132 setp(pbase(), epptr());
00133 delete[] buffer;
00134 }
00135 }
00136 };
00137 };
00138
00139 namespace OCL {
00140 namespace TCP {
00141 Socket::Socket( int socketID ) :
00142 std::ostream( new sockbuf(this) ),
00143 socket(socketID), begin(0), ptrpos(0), end(0)
00144 {
00145 }
00146
00147
00148 Socket::~Socket()
00149 {
00150 if( isValid() )
00151 {
00152 rawClose();
00153 }
00154 }
00155
00156 bool Socket::isValid() const
00157 {
00158 return socket >= 0;
00159 }
00160
00161 bool Socket::dataAvailable()
00162 {
00163 return isValid() && lineAvailable();
00164 }
00165
00166 bool Socket::lineAvailable()
00167 {
00168 int flags = fcntl(socket,F_GETFL);
00169 fcntl(socket,F_SETFL,flags | O_NONBLOCK);
00170 int ret =recv(socket,buffer,MSGLENGTH,MSG_PEEK);
00171 if(ret>0){
00172
00173 for(unsigned int i=0;i<MSGLENGTH;++i)
00174 if( buffer[i] == '\n'){
00175 ptrpos=i;
00176 return true;
00177 }
00178 return false;
00179 }else if(ret==0){
00180 rawClose();
00181 }
00182 return false;
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 }
00206
00207 void Socket::checkBufferOverflow()
00208 {
00209 if( end + MSGLENGTH >= BUFLENGTH ) {
00210 if( ptrpos - begin > MSGLENGTH ) {
00211 Logger::log() << Logger::Error << "Message length violation" << Logger::endl;
00212 rawClose();
00213 } else {
00214 memcpy( buffer, &buffer[begin], end - begin);
00215 }
00216 end -= begin;
00217 ptrpos -= begin;
00218 begin = 0;
00219 }
00220 }
00221
00222 std::string Socket::readLine()
00223 {
00224 if(dataAvailable()){
00225 if(0>recv(socket,buffer,sizeof(char[ptrpos+1]),MSG_WAITALL))
00226 return "";
00227
00228 return std::string(buffer,ptrpos);
00229 }
00230 return "";
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 }
00267
00268 void Socket::rawClose()
00269 {
00270 if( socket != -1 )
00271 {
00272 ::close(socket);
00273 }
00274 socket = -1;
00275 return;
00276 }
00277
00278 void Socket::close()
00279 {
00280 int _socket = socket;
00281 socket = -1;
00282
00283 if( _socket )
00284 {
00285
00286 int flags = fcntl( _socket, F_GETFL, 0 );
00287 if( flags == -1 )
00288 {
00289 flags = 0;
00290 }
00291 fcntl( _socket, F_SETFL, flags | O_NONBLOCK );
00292 ::send ( _socket, "104 Bye bye", 11, SEND_OPTIONS );
00293 ::close( _socket );
00294 }
00295 }
00296 };
00297 };