Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Types | Public Member Functions | Private Member Functions | Private Attributes
Arc::PayloadTCPSocket Class Reference

This class extends PayloadStream with TCP socket specific features. More...

#include <PayloadTCPSocket.h>

Inheritance diagram for Arc::PayloadTCPSocket:
Inheritance graph
[legend]
Collaboration diagram for Arc::PayloadTCPSocket:
Collaboration graph
[legend]

List of all members.

Public Types

typedef signed long long int Size_t

Public Member Functions

 PayloadTCPSocket (const char *hostname, int port, int timeout, Logger &logger)
 Constructor - connects to TCP server at specified hostname:port.
 PayloadTCPSocket (const std::string endpoint, int timeout, Logger &logger)
 Constructor - connects to TCP server at specified endpoint - hostname:port.
 PayloadTCPSocket (int s, int timeout, Logger &logger)
 Constructor - creates object of already connected socket.
 PayloadTCPSocket (PayloadTCPSocket &s)
 Copy constructor - inherits socket of copied object.
 PayloadTCPSocket (PayloadTCPSocket &s, Logger &logger)
 Copy constructor - inherits handle of copied object.
virtual ~PayloadTCPSocket (void)
virtual bool Get (char *buf, int &size)
 Extracts information from stream up to 'size' bytes.
virtual bool Get (std::string &buf)
 Read as many as possible (sane amount) of bytes into buf.
virtual std::string Get (void)
 Read as many as possible (sane amount) of bytes.
virtual bool Put (const char *buf, Size_t size)
 Push 'size' bytes from 'buf' into stream.
virtual bool Put (const std::string &buf)
 Push information from 'buf' into stream.
virtual bool Put (const char *buf)
 Push null terminated information from 'buf' into stream.
virtual operator bool (void)
 Returns true if stream is valid.
virtual bool operator! (void)
 Returns true if stream is invalid.
virtual int Timeout (void) const
 Query current timeout for Get() and Put() operations.
virtual void Timeout (int to)
 Set current timeout for Get() and Put() operations.
virtual Size_t Pos (void) const
 Returns current position in stream if supported.
virtual Size_t Size (void) const
 Returns size of underlying object if supported.
virtual Size_t Limit (void) const
 Returns position at which stream reading will stop if supported.
int GetHandle ()
void NoDelay (bool val)

Private Member Functions

int connect_socket (const char *hostname, int port)

Private Attributes

int handle_
bool acquired_
int timeout_
Loggerlogger

Detailed Description

This class extends PayloadStream with TCP socket specific features.

Definition at line 12 of file PayloadTCPSocket.h.


Member Typedef Documentation

typedef signed long long int Arc::PayloadStreamInterface::Size_t [inherited]

Definition at line 18 of file PayloadStream.h.


Constructor & Destructor Documentation

Arc::PayloadTCPSocket::PayloadTCPSocket ( const char *  hostname,
int  port,
int  timeout,
Logger logger 
)

Constructor - connects to TCP server at specified hostname:port.

Definition at line 132 of file PayloadTCPSocket.cpp.

                                                   :
  logger(logger)
{
  timeout_=timeout;
  handle_=connect_socket(hostname,port);
  acquired_=true;
}

Here is the call graph for this function:

Arc::PayloadTCPSocket::PayloadTCPSocket ( const std::string  endpoint,
int  timeout,
Logger logger 
)

Constructor - connects to TCP server at specified endpoint - hostname:port.

Definition at line 143 of file PayloadTCPSocket.cpp.

                                                               :
  logger(logger)
{
  std::string hostname = endpoint;
  std::string::size_type p = hostname.find(':');
  if(p == std::string::npos) return;
  int port = atoi(hostname.c_str()+p+1);
  hostname.resize(p);
  timeout_=timeout;
  handle_=connect_socket(hostname.c_str(),port);
  acquired_=true;
}

Here is the call graph for this function:

Arc::PayloadTCPSocket::PayloadTCPSocket ( int  s,
int  timeout,
Logger logger 
) [inline]

Constructor - creates object of already connected socket.

Socket is NOT closed in destructor.

Definition at line 26 of file PayloadTCPSocket.h.

                                                      :
    handle_(s),acquired_(false),timeout_(timeout),logger(logger) { };

Copy constructor - inherits socket of copied object.

Socket is NOT closed in destructor.

Definition at line 30 of file PayloadTCPSocket.h.

                                       :
    handle_(s.handle_),acquired_(false),timeout_(s.timeout_),logger(s.logger) { };

Copy constructor - inherits handle of copied object.

Handle is NOT closed in destructor.

Definition at line 34 of file PayloadTCPSocket.h.

                                                      :
    handle_(s.handle_),acquired_(false),timeout_(s.timeout_),logger(logger) { };

Definition at line 157 of file PayloadTCPSocket.cpp.

                                        {
  if(acquired_) { shutdown(handle_,2); close(handle_); };
}

Here is the call graph for this function:


Member Function Documentation

int Arc::PayloadTCPSocket::connect_socket ( const char *  hostname,
int  port 
) [private]

Definition at line 30 of file PayloadTCPSocket.cpp.

{
  struct addrinfo hint;
  memset(&hint, 0, sizeof(hint));
  hint.ai_family = AF_UNSPEC;
  hint.ai_socktype = SOCK_STREAM;
  hint.ai_protocol = IPPROTO_TCP;
  std::string port_str = tostring(port);
  struct addrinfo *info = NULL;
  int ret = getaddrinfo(hostname, port_str.c_str(), &hint, &info);
  if (ret != 0) {
    std::string err_str = gai_strerror(ret); 
    logger.msg(VERBOSE, "Failed to resolve %s (%s)", hostname, err_str);
       return -1;
  }
  int s = -1;
  for(struct addrinfo *info_ = info;info_;info_=info_->ai_next) {
    logger.msg(VERBOSE,"Trying to connect %s(%s):%d",
                     hostname,info_->ai_family==AF_INET6?"IPv6":"IPv4",port);
    s = ::socket(info_->ai_family, info_->ai_socktype, info_->ai_protocol);
    if(s == -1) {
      logger.msg(VERBOSE, "Failed to create socket to %s(%s):%d - %s",
                        hostname,info_->ai_family==AF_INET6?"IPv6":"IPv4",port,
                        Arc::StrError(errno));
      continue;
    }
#ifndef WIN32
    // In *NIX we can use non-blocking socket because poll() will 
    // be used for waiting.
    int s_flags = ::fcntl(s, F_GETFL, 0);
    if(s_flags != -1) {
      ::fcntl(s, F_SETFL, s_flags | O_NONBLOCK);
    } else {
      logger.msg(VERBOSE, "Failed to get TCP socket options for connection"
                        " to %s(%s):%d - timeout won't work - %s",
                        hostname,info_->ai_family==AF_INET6?"IPv6":"IPv4",port,
                        Arc::StrError(errno));
    }
    if(::connect(s, info_->ai_addr, info_->ai_addrlen) == -1) {
      if(errno != EINPROGRESS) {
        logger.msg(VERBOSE, "Failed to connect to %s(%s):%i - %s",
                        hostname,info_->ai_family==AF_INET6?"IPv6":"IPv4",port,
                        Arc::StrError(errno));
        close(s); s = -1;
        continue;
      }
      int pres;
      // Second resolution is enough
      time_t c_time = time(NULL);
      time_t f_time = c_time + timeout_;
      struct pollfd fd;
      for(;;) {
        fd.fd=s; fd.events=POLLOUT | POLLPRI; fd.revents=0;
        pres = ::poll(&fd,1,(f_time-c_time)*1000);
        // Checking for operation interrupted by signal
        if((pres == -1) && (errno == EINTR)) {
          c_time = time(NULL);
          // TODO: protection against time jumping backward.
          if(((int)(f_time - c_time)) < 0) c_time = f_time; 
        }
        break;
      }
      if(pres == 0) {
        logger.msg(VERBOSE, "Timeout connecting to %s(%s):%i - %i s",
                        hostname,info_->ai_family==AF_INET6?"IPv6":"IPv4",port,
                        timeout_);
        close(s); s = -1;
        continue;
      }
      if(pres != 1) {
        logger.msg(VERBOSE, "Failed waiting connection to %s(%s):%i - %s",
                        hostname,info_->ai_family==AF_INET6?"IPv6":"IPv4",port,
                        Arc::StrError(errno));
        close(s); s = -1;
        continue;
      }
      // man connect says one has to check SO_ERROR, but poll() returns
      // POLLERR and POLLHUP so we can use them directly. 
      if(fd.revents & (POLLERR | POLLHUP)) {
        logger.msg(VERBOSE, "Failed to connect to %s(%s):%i",
                        hostname,info_->ai_family==AF_INET6?"IPv6":"IPv4",port);
        close(s); s = -1;
        continue;
      }
    }
#else
    if(::connect(s, info_->ai_addr, info_->ai_addrlen) == -1) {
      logger.msg(VERBOSE, "Failed to connect to %s(%s):%i",
                        hostname,info_->ai_family==AF_INET6?"IPv6":"IPv4",port);
      close(s); s = -1;
      continue;
    };
#endif
    break;
  };
  if(s == -1) {
    logger.msg(VERBOSE, "Failed to establish connection to %s:%i", hostname, port);
  };
  freeaddrinfo(info);
  return s;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::PayloadTCPSocket::Get ( char *  buf,
int &  size 
) [virtual]

Extracts information from stream up to 'size' bytes.

'size' contains number of read bytes on exit. Returns true in case of success.

Implements Arc::PayloadStreamInterface.

Definition at line 161 of file PayloadTCPSocket.cpp.

                                              {
  if(handle_ == -1) return false;
  ssize_t l = size;
  size=0;
#ifndef WIN32
  struct pollfd fd;
  fd.fd=handle_; fd.events=POLLIN | POLLPRI | POLLERR; fd.revents=0;
  if(::poll(&fd,1,timeout_*1000) != 1) return false;
  if(!(fd.revents & (POLLIN | POLLPRI))) return false;
#endif
  l=::recv(handle_,buf,l,0);
  if(l == -1) return false;
  size=l;
#ifndef WIN32
  if((l == 0) && (fd.revents && POLLERR)) return false;
#else
  if(l == 0) return false;
#endif
  return true;
}
bool Arc::PayloadTCPSocket::Get ( std::string &  buf) [virtual]

Read as many as possible (sane amount) of bytes into buf.

Implements Arc::PayloadStreamInterface.

Definition at line 182 of file PayloadTCPSocket.cpp.

                                         {
  char tbuf[1024];
  int l = sizeof(tbuf);
  bool result = Get(tbuf,l);
  buf.assign(tbuf,l);
  return result;
}

Here is the call graph for this function:

virtual std::string Arc::PayloadTCPSocket::Get ( void  ) [inline, virtual]

Read as many as possible (sane amount) of bytes.

Implements Arc::PayloadStreamInterface.

Definition at line 39 of file PayloadTCPSocket.h.

{ std::string buf; Get(buf); return buf; };

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 50 of file PayloadTCPSocket.h.

{ return handle_; };

Here is the caller graph for this function:

virtual Size_t Arc::PayloadTCPSocket::Limit ( void  ) const [inline, virtual]

Returns position at which stream reading will stop if supported.

That may be not same as Size() if instance is meant to provide access to only part of underlying obejct.

Implements Arc::PayloadStreamInterface.

Definition at line 49 of file PayloadTCPSocket.h.

{ return 0; };
void Arc::PayloadTCPSocket::NoDelay ( bool  val)

Definition at line 214 of file PayloadTCPSocket.cpp.

                                       {
  if(handle_ == -1) return;
  int flag = val?1:0;

#ifdef WIN32
 ::setsockopt(handle_,IPPROTO_TCP,TCP_NODELAY,(const char*)(&flag),sizeof(flag));
#else
 ::setsockopt(handle_,IPPROTO_TCP,TCP_NODELAY,&flag,sizeof(flag));
#endif

}

Here is the caller graph for this function:

virtual Arc::PayloadTCPSocket::operator bool ( void  ) [inline, virtual]

Returns true if stream is valid.

Implements Arc::PayloadStreamInterface.

Definition at line 43 of file PayloadTCPSocket.h.

{ return (handle_ != -1); };
virtual bool Arc::PayloadTCPSocket::operator! ( void  ) [inline, virtual]

Returns true if stream is invalid.

Implements Arc::PayloadStreamInterface.

Definition at line 44 of file PayloadTCPSocket.h.

{ return (handle_ == -1); };
virtual Size_t Arc::PayloadTCPSocket::Pos ( void  ) const [inline, virtual]

Returns current position in stream if supported.

Implements Arc::PayloadStreamInterface.

Definition at line 47 of file PayloadTCPSocket.h.

{ return 0; };
bool Arc::PayloadTCPSocket::Put ( const char *  buf,
Size_t  size 
) [virtual]

Push 'size' bytes from 'buf' into stream.

Returns true on success.

Implements Arc::PayloadStreamInterface.

Definition at line 190 of file PayloadTCPSocket.cpp.

                                                      {
  ssize_t l;
  if(handle_ == -1) return false;
  time_t start = time(NULL);
  for(;size;) {
#ifndef WIN32
    struct pollfd fd;
    fd.fd=handle_; fd.events=POLLOUT | POLLERR; fd.revents=0;
    int to = timeout_-(unsigned int)(time(NULL)-start);
    if(to < 0) to=0;
    if(::poll(&fd,1,to*1000) != 1) return false;
    if(!(fd.revents & POLLOUT)) return false;
#endif
    l=::send(handle_, buf, size, 0);
    if(l == -1) return false;
    buf+=l; size-=l;
#ifdef WIN32
    int to = timeout_-(unsigned int)(time(NULL)-start);
    if(to < 0) return false;
#endif
  };  
  return true;
}

Here is the caller graph for this function:

virtual bool Arc::PayloadTCPSocket::Put ( const std::string &  buf) [inline, virtual]

Push information from 'buf' into stream.

Returns true on success.

Implements Arc::PayloadStreamInterface.

Definition at line 41 of file PayloadTCPSocket.h.

{ return Put(buf.c_str(),buf.length()); };

Here is the call graph for this function:

Here is the caller graph for this function:

virtual bool Arc::PayloadTCPSocket::Put ( const char *  buf) [inline, virtual]

Push null terminated information from 'buf' into stream.

Returns true on success.

Implements Arc::PayloadStreamInterface.

Definition at line 42 of file PayloadTCPSocket.h.

{ return Put(buf,buf?strlen(buf):0); };

Here is the call graph for this function:

Here is the caller graph for this function:

virtual Size_t Arc::PayloadTCPSocket::Size ( void  ) const [inline, virtual]

Returns size of underlying object if supported.

Implements Arc::PayloadStreamInterface.

Definition at line 48 of file PayloadTCPSocket.h.

{ return 0; };
virtual int Arc::PayloadTCPSocket::Timeout ( void  ) const [inline, virtual]

Query current timeout for Get() and Put() operations.

Implements Arc::PayloadStreamInterface.

Definition at line 45 of file PayloadTCPSocket.h.

{ return timeout_; };
virtual void Arc::PayloadTCPSocket::Timeout ( int  to) [inline, virtual]

Set current timeout for Get() and Put() operations.

Implements Arc::PayloadStreamInterface.

Definition at line 46 of file PayloadTCPSocket.h.

{ timeout_=to; };

Member Data Documentation

Definition at line 16 of file PayloadTCPSocket.h.

Definition at line 15 of file PayloadTCPSocket.h.

Definition at line 18 of file PayloadTCPSocket.h.

Definition at line 17 of file PayloadTCPSocket.h.


The documentation for this class was generated from the following files: