00001 #include <iostream>
00002
00003
00004 #include "SysPlusPlus/Logger.h"
00005 #include "SysPlusPlus/syscall.h"
00006
00007 #include "ComPlusPlus/Socket.h"
00008 #include <errno.h>
00009 #include "SysPlusPlus/ComException.h"
00010
00011 #include <arpa/inet.h>
00012
00013 #include <sys/socket.h>
00014 #include <sys/un.h>
00015
00019 compp::Socket::Socket ( ) : Comm (_CommDefaultReadAheadBufferSize) {
00020
00021 compp::GenCfg * Cfg = (compp::GenCfg*) compp::GenCfg::Instance();
00022
00023 this->UseDns = Cfg->GetCommUseDNS() ;
00024 this->LingerSeconds = Cfg->GetCommLingerTime();
00025
00026 }
00027
00028 compp::Socket::Socket ( unsigned int buffsz ) : Comm ( buffsz ) {
00029
00030 compp::GenCfg * Cfg = (compp::GenCfg*) compp::GenCfg::Instance();
00031
00032 this->UseDns = Cfg->GetCommUseDNS() ;
00033 this->LingerSeconds = Cfg->GetCommLingerTime();
00034
00035 }
00036
00040 compp::Socket::~Socket ( ) {
00041
00042 }
00043
00050 void compp::Socket::_MkIPAddrIPV4( const std::string &addr, struct in_addr *ad ) {
00051 struct hostent *hent;
00052
00053
00054 in_addr_t t;
00055 if ( (t = inet_addr ( addr.c_str() )) != INADDR_NONE ) {
00056 memcpy ( (void*) ad, (void*)&t, sizeof(t)) ;
00057 return;
00058 }
00059 if ( t == INADDR_NONE ) {
00060 if ( this->GetUseDNS() ) {
00061 if (NULL == (hent = gethostbyname ( addr.c_str() ))) {
00062 throw syspp::ComException ( "compp::Socket::_MkIPAddrIPV4(). Could not resolve name.");
00063 } else {
00064 std::memmove( (void*) ad, (void*) *hent->h_addr_list , sizeof(struct in_addr));
00065 }
00066 } else {
00067 throw syspp::ComException ( "compp::Socket::_MkIPAddrIPV4() Cannot resolve address and resolver not used" );
00068 }
00069 }
00070 }
00071
00072
00073
00080 void compp::Socket::_MkSockaddrIPV4( const std::string &addr, const int port, struct sockaddr_in *ad ) {
00081 struct hostent *hent;
00082 struct in_addr adv4;
00083
00084 in_addr_t t;
00085 if ( (t = inet_addr ( addr.c_str() )) != INADDR_NONE ) {
00086 memcpy ( (void*) ad, (void*)&t, sizeof(t)) ;
00087 }
00088 adv4.s_addr = t;
00089 if ( t == INADDR_NONE ) {
00090
00091 if ( this->GetUseDNS() ) {
00092
00093 if (NULL == (hent = gethostbyname ( addr.c_str() ))) {
00094 throw syspp::ComException ( "compp::SocketTcp::Connect(). Could not resolve name.");
00095 } else {
00096 std::memmove( (void*) &(adv4), (void*) *hent->h_addr_list , sizeof(adv4));
00097 ad->sin_addr.s_addr = adv4.s_addr;
00098 }
00099 } else {
00100 throw syspp::ComException ( "compp::Socket::_MkSockaddrIPV4() Cannot resolve address and resolver not used" );
00101 }
00102 } else {
00103 ad->sin_addr.s_addr = adv4.s_addr;
00104 }
00105
00106 ad->sin_family = AF_INET;
00107 ad->sin_port = htons(port);
00108 }
00109
00113 bool compp::Socket::SetSockOptLinger ( int secs ) {
00114
00115
00116 if ( this->fd == -1 )
00117 return false;
00118
00119 struct linger li;
00120
00121 if ( 0 == (secs) ) {
00122 li.l_onoff = 0;
00123 li.l_linger = 0;
00124 } else {
00125 li.l_onoff = 1;
00126 li.l_linger = secs;
00127 }
00128
00129 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_LINGER, (void*)&li, sizeof(li) )) {
00130 return false;
00131 }
00132
00133 return true;
00134 }
00135
00140 bool compp::Socket::SetSockOptReuseAddress ( bool yesno ) {
00141 int opt;
00142
00143 if ( yesno == true )
00144 opt = 1;
00145 else
00146 opt = 0;
00147
00148 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(opt) )) {
00149 return false;
00150 }
00151
00152 return true;
00153 }
00154
00159 bool compp::Socket::SetSockOptKeepAlive ( bool yesno ) {
00160 int opt;
00161
00162 if ( yesno == true )
00163 opt = 1;
00164 else
00165 opt = 0;
00166
00167 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&opt, sizeof(opt) )) {
00168 return false;
00169 }
00170
00171 return true;
00172 }
00173
00177 bool compp::Socket::SetSockOptOobinline( bool yes ) {
00178 int opt;
00179
00180 if ( yes == true )
00181 opt = 1;
00182 else
00183 opt = 0;
00184
00185 #ifndef SO_OOBINLINE
00186 return false;
00187 #else
00188 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_OOBINLINE, (void*)&opt, sizeof(opt) )) {
00189 return false;
00190 }
00191 #endif
00192
00193 return true;
00194 }
00195
00200 bool compp::Socket::SetSockOptDontroute (bool yes ) {
00201 int opt;
00202
00203 if ( yes == true )
00204 opt = 1;
00205 else
00206 opt = 0;
00207
00208 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_DONTROUTE, (void*)&opt, sizeof(opt) )) {
00209 return false;
00210 }
00211
00212 return true;
00213 }
00214
00220 bool compp::Socket::SetSockOptSndBuf ( int bytes ) {
00221 int opt;
00222 opt = bytes;
00223 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_SNDBUF, (void*)&opt, sizeof(opt) )) {
00224 return false;
00225 }
00226 return true;
00227 }
00228
00233 bool compp::Socket::SetSockOptRcvBuf ( int bytes) {
00234 int opt;
00235 opt = bytes;
00236 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_RCVBUF, (void*)&opt, sizeof(opt) )) {
00237 return false;
00238 }
00239 return true;
00240 }
00241
00246 bool compp::Socket::SetSockOptPriority( bool yes) {
00247
00248 int opt;
00249
00250 if ( yes == true )
00251 opt = 1;
00252 else
00253 opt = 0;
00254
00255 #ifndef SO_PRIORITY
00256 return false;
00257 #else
00258 if ( 0 != syspp::Call::Setsockopt (this->fd, SOL_SOCKET, SO_PRIORITY, (void*)&opt, sizeof(opt) )) {
00259 return false;
00260 }
00261 #endif
00262
00263 return true;
00264 }
00265
00266
00270 bool compp::Socket::_Connect( const std::string &addr, const int port ){
00271 int ret ;
00272 struct sockaddr_in ad;
00273
00274 _MkSockaddrIPV4(addr, port, &ad);
00275
00276 errno = 0;
00277 ret = syspp::Call::Connect ( this->fd, (struct sockaddr*) &ad, sizeof(struct sockaddr_in));
00278
00279 if (ret == -1 && errno != EINPROGRESS ) {
00280 return false;
00281 }
00282
00283 this->IsOpen=true;
00284 return true;
00285 }
00306 int compp::Socket::Send ( const void *buf, size_t len, int flags=0) {
00307 int ret;
00308 ret = syspp::Call::Send(this->fd, buf, len, flags);
00309 if ( ret == -1 ) {
00310 perror ("UDP WRITE");
00311 std::cout << "Comm Errno " << errno << "\n";
00312 throw syspp::ComException ( "Error in send procedure" );
00313 }
00314 return ret;
00315 }
00316
00320 int compp::Socket::Send ( const void *buf, size_t len){
00321 int ret;
00322
00323 ret = syspp::Call::Send(this->fd, buf, len, 0) ;
00324 if ( ret == -1 ) {
00325 perror ("UDP WRITE");
00326 std::cout << "Comm Errno " << errno << "\n";
00327 throw syspp::ComException ( "Error in send procedure" );
00328 }
00329 return ret;
00330 }
00331
00332
00336 int compp::Socket::Recv(void *buf, int len, int flags) {
00337 int ret ;
00338 ret = syspp::Call::Recv(this->fd, buf, len, flags);
00339 if ( ret == -1 && errno != EAGAIN ) {
00340 throw syspp::ComException( "Error in Recvfrom");
00341 }
00342 return ret;
00343 }
00344
00350 int compp::Socket::Recvfrom(void *buf, int len, int flags, struct sockaddr *from, int *fromlen){
00351 int ret;
00352 ret = syspp::Call::Recvfrom(this->fd, buf, len, flags, from, fromlen);
00353
00354 if ( ret == -1 && errno != EAGAIN ) {
00355 throw syspp::ComException( "Error in Recvfrom");
00356 }
00357
00358 return ret;
00359 }
00360
00361
00365 void compp::Socket::SetLingerTime ( int secs ) {
00366 LingerSeconds = secs ;
00367 }
00368
00372 int compp::Socket::GetLingerTime ( ) const {
00373 return LingerSeconds;
00374 }
00375
00376
00380 bool compp::Socket::GetUseDNS () const {
00381 return this->UseDns;
00382 }
00383
00387 void compp::Socket::SetUseDNS (bool val) {
00388 this->UseDns = val;
00389
00390 }
00391
00392
00393 void compp::Socket::SetContextString ( std::string & s ) {
00394 ContextString = s;
00395 }
00396
00397 std::string compp::Socket::GetContextString ( ) {
00398 return ContextString;
00399 }
00400
00401
00402
00403
00404 const std::string compp::Socket::GetSocketAddress() const {
00405
00406 return SocketAddress ;
00407
00408 }
00409
00410 const int compp::Socket::GetSocketPort() const {
00411
00412
00413 return SocketPort ;
00414
00415
00416 }
00417
00418
00419