rllib  1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Private Attributes | List of all members
rlSocket Class Reference

#include <rlsocket.h>

Inheritance diagram for rlSocket:
Inheritance graph
[legend]

Public Types

enum  SocketEnum {
  SOCKET_ERR = -1, SETSOCKOPT_ERR = -2, LISTEN_ERR = -3, ACCEPT_ERR = -4,
  INET_ADDR_ERR = -5, CONNECT_ERR = -6, PORT_ERR = -7
}
 

Public Member Functions

 rlSocket (const char *adr, int port, int active)
 
 rlSocket (int socket)
 
virtual ~rlSocket ()
 
void setAdr (const char *adr)
 
void setPort (int port)
 
int getPort ()
 
void setActive (int active)
 
int read (void *buf, int len, int timeout=0)
 
int readStr (char *buf, int len, int timeout=0)
 
int write (const void *buf, int len)
 
int printf (const char *format,...)
 
int connect ()
 
int disconnect ()
 
int select (int timeout=0)
 
int isConnected ()
 
int setIPVersion (int version)
 
int getIPVersion ()
 
int sendProcessViewBrowserButtonEvent (int id)
 
int rlGetsockopt (int level, int optname)
 
int rlSetsockopt (int level, int optname)
 

Static Public Member Functions

static int rlGetsockopt (int sockfd, int level, int optname, void *optval, int *optlen)
 
static int rlSetsockopt (int sockfd, int level, int optname, const void *optval, int optlen)
 

Public Attributes

int s
 
unsigned char sockaddr [16+48]
 

Private Attributes

char adr [132]
 
int port
 
int active
 
int os
 
int first
 
int prefer_ipv6
 
int rl_ipversion
 

Detailed Description

class for encapsulating TCP/IP socket calls

Definition at line 48 of file rlsocket.h.

Member Enumeration Documentation

Enumerator:
SOCKET_ERR 
SETSOCKOPT_ERR 
LISTEN_ERR 
ACCEPT_ERR 
INET_ADDR_ERR 
CONNECT_ERR 
PORT_ERR 

Definition at line 52 of file rlsocket.h.

{
SOCKET_ERR = -1,
LISTEN_ERR = -3,
ACCEPT_ERR = -4,
PORT_ERR = -7
};

Constructor & Destructor Documentation

rlSocket::rlSocket ( const char *  adr,
int  port,
int  active 
)
     construct a new rlSocket but do not connect
     adr  = hostname | dotted address
     port = port number of socket
     active = 0 wait for connections with accept()
     active = 1 open the connection with connect()
     active = 2 neither accept() nor connect()
 

Definition at line 94 of file rlsocket.cpp.

{
rlwsa(); // init sockets on windows
setAdr(a);
port = p;
active = act;
s = -1;
os = -1;
first = 1;
memset(sockaddr,0,sizeof(sockaddr));
}
rlSocket::rlSocket ( int  socket)
     construct a new rlSocket
     use connection on open socket
 

Definition at line 107 of file rlsocket.cpp.

{
adr[0] = '\0';
port = -1;
active = 0;
s = socket;
os = -1;
first = 0;
memset(sockaddr,0,sizeof(sockaddr));
}
rlSocket::~rlSocket ( )
virtual
     destruct the socket
     attention if active = 0 the socket will still be bound to port
 

Definition at line 119 of file rlsocket.cpp.

{
if(os != -1 && active == 0)
{
#ifdef RLWIN32
closesocket(os);
#else
close(os);
#endif
}
}

Member Function Documentation

int rlSocket::connect ( )
     connect
     return >= 0 socket used
     return < 0  error (see: enum SocketEnum)
 

Definition at line 245 of file rlsocket.cpp.

{
int option;
int ret;
#ifdef __VMS
size_t socklen = sizeof(struct sockaddr);
#else
socklen_t socklen = sizeof(struct sockaddr);
#endif
struct sockaddr_in localAddr;
struct sockaddr_in remoteAddr;
struct hostent *host;
struct in_addr RemoteIpAddress;
#ifdef AF_INET6_IS_AVAILABLE
struct addrinfo hints0, hints1;
struct addrinfo *res, *ressave;
int n;
char portstr[32];
#endif
if(port <= 0) return PORT_ERR;
if(port >= 256*256) return PORT_ERR;
if(active == 0)
{ // accept calls
s = -1;
if(rl_ipversion == 4)
{
if(first == 1)
{
// create a socket
os = socket(AF_INET,SOCK_STREAM,0);
if(os == -1) return SOCKET_ERR;
// set socket options
#ifdef __VMS
option = 1;
if(setsockopt(os,SOL_SOCKET,SO_KEEPALIVE,&option,sizeof(option)) < 0)
{
}
#endif
option = 1;
#ifdef RLWIN32
setsockopt(os,SOL_SOCKET,SO_REUSEADDR,(const char *) &option,sizeof(option));
#else
setsockopt(os,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));
#endif
// Bind our server to the agreed upon port number.
memset(&localAddr,0,sizeof(localAddr));
localAddr.sin_port = htons((short) port);
localAddr.sin_family = AF_INET;
bind:
ret = bind(os, (struct sockaddr *) &localAddr, sizeof(localAddr));
if(ret == -1)
{
goto bind;
}
// Prepare to accept client connections. Allow up to 5 pending
// connections.
ret = listen(os, 5);
if(ret == -1) return LISTEN_ERR;
}
first = 0;
// accept connections
s = accept(os, (struct sockaddr *) &sockaddr[0], &socklen);
if(s == -1) return ACCEPT_ERR;
}
else if(rl_ipversion == 6)
{
#ifdef AF_INET6_IS_AVAILABLE
if(first == 1)
{
memset(&hints0,0,sizeof(hints0));
hints0.ai_flags = AI_PASSIVE;
//hints0.ai_family = AF_UNSPEC;
hints0.ai_family = AF_INET6;
hints0.ai_socktype = SOCK_STREAM;
sprintf(portstr,"%d",port);
//::printf("server getaddrinfo(%s,%s)\n", adr, portstr);
n = getaddrinfo(adr, portstr, &hints0, &res);
if(n != 0)
{
#ifndef RLWIN32
::printf("rlSocket:tcp_listen error for %s port=%s : %s\n", adr, portstr, gai_strerror(n));
#endif
return -1;
}
//::printf("done\n");
ressave = res;
bindv6:
do
{
os = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(os < 0) continue; // error, try next one
#ifdef __VMS
option = 1;
if(setsockopt(os,SOL_SOCKET,SO_KEEPALIVE,&option,sizeof(option)) < 0)
{
}
#endif
option = 1;
#ifdef RLWIN32
setsockopt(os,SOL_SOCKET,SO_REUSEADDR,(const char *) &option,sizeof(option));
#else
setsockopt(os,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option));
#endif
if(bind(os, res->ai_addr, res->ai_addrlen) == 0) break; // success
s = os;
disconnect(); // bind error, close and try next one
}
while((res = res->ai_next) != NULL);
if(res == NULL) // errno from final socket() or bind()
{
::printf("warning: could not bind to port=%d\n", port);
goto bindv6;
}
// Prepare to accept client connections. Allow up to 5 pending
// connections
ret = listen(os, 5);
freeaddrinfo(ressave);
if(ret == -1) return LISTEN_ERR;
}
first = 0;
// accept connections
s = accept(os, (struct sockaddr *) &sockaddr[0], &socklen);
if(s == -1) return ACCEPT_ERR;
#else
::printf("rlSocket:ERROR IPV6 not available on this platform\n");
#endif
}
else
{
::printf("rlSocket:ERROR: rl_ipversion=%d not known\n", rl_ipversion);
}
} // end active == 0
else if(active == 1)
{
//::printf("debug: adr=%s port=%d\n",adr,port);
s = -1;
if(rl_ipversion == 4)
{
os = socket(AF_INET,SOCK_STREAM,0);
if(os == -1) return SOCKET_ERR;
s = os;
//::printf("debug: gethostbyname\n");
// fill destblk structure
host = gethostbyname(adr);
if(host == NULL)
{
// See if the host is specified in "dot address" form
RemoteIpAddress.s_addr = inet_addr(adr);
if(RemoteIpAddress.s_addr == INADDR_NONE)
{
s = -1;
return INET_ADDR_ERR; // -1
}
}
else
{
memcpy(&RemoteIpAddress,host->h_addr,host->h_length);
}
memset(&remoteAddr,0,sizeof(remoteAddr));
remoteAddr.sin_family = AF_INET;
remoteAddr.sin_port = htons((short) port);
remoteAddr.sin_addr = RemoteIpAddress;
//::printf("debug: connect\n");
ret = ::connect(s, (struct sockaddr *) &remoteAddr, sizeof(remoteAddr));
//::printf("debug: connect ret=%d\n",ret);
if(ret == -1)
{
disconnect(); // close s = os
return CONNECT_ERR;
}
}
else if(rl_ipversion == 6)
{
#ifdef AF_INET6_IS_AVAILABLE
sprintf(portstr,"%d",port);
memset(&hints1, 0, sizeof(hints1));
hints1.ai_family = AF_UNSPEC;
hints1.ai_socktype = SOCK_STREAM;
n = getaddrinfo(adr, portstr, &hints1, &res);
if(n != 0)
{
#ifndef RLWIN32
::printf("rlSocket:tcp_connect error for %s port=%s : %s\n", adr, portstr, gai_strerror(n));
#endif
return -1;
}
ressave = res;
do
{
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(s < 0) continue; // ignore this one
if(::connect(s, res->ai_addr, res->ai_addrlen) == 0) break; // success
disconnect(); // ignore this one
}
while((res = res->ai_next) != NULL);
if(res == NULL) ::printf("rlSocket:tcp_connect error for %s port=%s\n", adr, portstr);
freeaddrinfo(ressave);
#else
::printf("rlSocket:ERROR IPV6 not available on this platform\n");
#endif
}
else
{
::printf("rlSocket:ERROR: rl_ipversion=%d not known\n", rl_ipversion);
}
}
return s;
}
int rlSocket::disconnect ( )
     disconnect
     return = 0
 

Definition at line 464 of file rlsocket.cpp.

{
if(s != -1)
{
#ifdef RLWIN32
closesocket(s);
#else
close(s);
#endif
}
s = -1;
return 0;
}
int rlSocket::getIPVersion ( )
     return == 4 IPV4
     return == 6 IPV6
 

Definition at line 530 of file rlsocket.cpp.

{
return rl_ipversion;
}
int rlSocket::getPort ( )
     get port
 

Definition at line 145 of file rlsocket.cpp.

{
return port;
}
int rlSocket::isConnected ( )
     return == 1 socket is connected
     return == 0 socket is not connected
 

Definition at line 478 of file rlsocket.cpp.

{
if(s == -1) return 0;
return 1;
}
int rlSocket::printf ( const char *  format,
  ... 
)
     similar to printf
     return > 0 length of data written
     return < 0 error
 

Definition at line 505 of file rlsocket.cpp.

{
int ret;
char message[rl_PRINTF_LENGTH]; // should be big enough
va_list ap;
va_start(ap,format);
ret = rlvsnprintf(message, rl_PRINTF_LENGTH - 1, format, ap);
va_end(ap);
if(ret < 0) return ret;
return write(message,strlen(message));
}
int rlSocket::read ( void *  buf,
int  len,
int  timeout = 0 
)
     read a block of data
     len = length of data to be read
     timeout = 0 wait indefinite
     timeout > 0 wait at maximum for timeout milliseconds
     return > 0 length of message read
     return == 0 timeout
     return < 0 error
 

Definition at line 155 of file rlsocket.cpp.

{
int i,ret;
char *cbuf;
if(s == -1) return -1;
if(select(timeout) == 0) return 0; // timeout
cbuf = (char *) buf;
i = 0;
while(i < len)
{
ret = recv(s,&cbuf[i],len-i,0);
if(ret <= 0)
{
return -1;
}
i += ret;
if(i < len)
{
if(select(timeout) == 0) return 0; // timeout
}
}
return i;
}
int rlSocket::readStr ( char *  buf,
int  len,
int  timeout = 0 
)
     read a '
' terminated string len = max length of data to be read timeout = 0 wait indefinite timeout > 0 wait at maximum for timeout milliseconds return > 0 length of message read return == 0 timeout return < 0 error

Definition at line 183 of file rlsocket.cpp.

{
int ret,i;
if(s == -1) return -1;
if(select(timeout) == 0) return 0; // timeout
i = 0;
while(1)
{
#ifdef RLWIN32
tryagain:
#endif
ret = recv(s,&buf[i],1,0);
if(ret <= 0)
{
#ifdef RLWIN32
if(WSAEWOULDBLOCK == WSAGetLastError()) goto tryagain;
#endif
buf[i] = '\0';
return -1;
}
if(buf[i] == '\n')
{
buf[i+1] = '\0';
return i+1;
}
if(i >= len-1)
{
buf[i+1] = '\0';
return i+1;
}
i++;
}
}
int rlSocket::rlGetsockopt ( int  sockfd,
int  level,
int  optname,
void *  optval,
int *  optlen 
)
static
     portable version of getsockopt
 

Definition at line 535 of file rlsocket.cpp.

{
#ifdef RLWIN32
return getsockopt(sockfd, level, optname, (char *) optval, optlen);
#elif defined(__VMS)
size_t len = *optlen;
int ret = getsockopt(sockfd, level, optname, optval, &len);
*optlen = len;
return ret;
#else
socklen_t len = *optlen;
int ret = getsockopt(sockfd, level, optname, optval, &len);
*optlen = len;
return ret;
#endif
}
int rlSocket::rlGetsockopt ( int  level,
int  optname 
)
     get an option from this->s
 

Definition at line 561 of file rlsocket.cpp.

{
int option = 1;
int len = sizeof(option);
return rlGetsockopt(s,level,optname,&option,&len);
}
int rlSocket::rlSetsockopt ( int  sockfd,
int  level,
int  optname,
const void *  optval,
int  optlen 
)
static
     portable version of setsockopt
 

Definition at line 552 of file rlsocket.cpp.

{
#ifdef RLWIN32
return setsockopt(sockfd, level, optname, (const char *) optval, optlen);
#else
return setsockopt(sockfd, level, optname, optval, optlen);
#endif
}
int rlSocket::rlSetsockopt ( int  level,
int  optname 
)
     set an option on this->s
 

Definition at line 568 of file rlsocket.cpp.

{
int option = 1;
return rlSetsockopt(s,level,optname,&option,sizeof(option));
}
int rlSocket::select ( int  timeout = 0)
     wait for data arriving on socket
     timeout > 0 timeout in milliseconds
     timeout == 0 indefinite timeout
     return = 1 DATA_AVAILABLE
     return = 0 TIMEOUT
 

Definition at line 484 of file rlsocket.cpp.

{
struct timeval timout;
fd_set wset,rset,eset;
int ret,maxfdp1;
if(timeout == 0) return 1;
/* setup sockets to read */
maxfdp1 = s+1;
FD_ZERO(&rset);
FD_SET (s,&rset);
FD_ZERO(&wset);
FD_ZERO(&eset);
timout.tv_sec = timeout / 1000;
timout.tv_usec = (timeout % 1000) * 1000;
ret = ::select(maxfdp1,&rset,&wset,&eset,&timout);
if(ret == 0) return 0; /* timeout */
return 1;
}
int rlSocket::sendProcessViewBrowserButtonEvent ( int  id)
     This method is intendet for data providers implemented as ProcessViewServer
 

Definition at line 518 of file rlsocket.cpp.

{
return printf("QPushButton(%d)\n",id);
}
void rlSocket::setActive ( int  active)
     set port active = 0|1
 

Definition at line 150 of file rlsocket.cpp.

{
active = act;
}
void rlSocket::setAdr ( const char *  adr)
     set adr to a different adr than in the constructor
 

Definition at line 132 of file rlsocket.cpp.

{
adr[0] = '\0';
if(a == NULL) return;
if((strlen(a)+1) > sizeof(adr)) return;
strcpy(adr,a);
}
int rlSocket::setIPVersion ( int  version)
     default: prefer IPV4
     if(ip==6) prefer IPV6
     else      prefer IPV4
 

Definition at line 523 of file rlsocket.cpp.

{
if(version == 6) rl_ipversion = 6;
else rl_ipversion = 4;
return rl_ipversion;
}
void rlSocket::setPort ( int  port)
     set port to a different port than in the constructor
 

Definition at line 140 of file rlsocket.cpp.

{
port = p;
}
int rlSocket::write ( const void *  buf,
int  len 
)
     write a block of data
     return > 0 length of data written
     return < 0 error
 

Definition at line 220 of file rlsocket.cpp.

{
int ret,bytes_left,first_byte;
const char *cbuf;
if(s == -1) return -1;
cbuf = (char *) buf;
bytes_left = len;
first_byte = 0;
while(bytes_left > 0)
{
ret = send(s,&cbuf[first_byte],bytes_left,MSG_NOSIGNAL);
if(ret <= 0)
{
return -1;
}
bytes_left -= ret;
first_byte += ret;
}
return first_byte;
}

Member Data Documentation

int rlSocket::active
private

Definition at line 253 of file rlsocket.h.

char rlSocket::adr[132]
private

Definition at line 251 of file rlsocket.h.

int rlSocket::first
private

Definition at line 255 of file rlsocket.h.

int rlSocket::os
private

Definition at line 254 of file rlsocket.h.

int rlSocket::port
private

Definition at line 252 of file rlsocket.h.

int rlSocket::prefer_ipv6
private

Definition at line 256 of file rlsocket.h.

int rlSocket::rl_ipversion
private

Definition at line 257 of file rlsocket.h.

int rlSocket::s
     this is the real socket used for communication
     s >= 0  connected
     s == -1 disconnected
 

Definition at line 193 of file rlsocket.h.

unsigned char rlSocket::sockaddr[16+48]
      this array can be casted to (struct sockaddr *) &sockaddr[0];
      in case of active==0 it will store sockaddr of the last client
      (48 bytes spare)
      struct sockaddr {
        unsigned short    sa_family;    // address family, AF_xxx
        char              sa_data[14];  // 14 bytes of protocol address
      };
IPv4 AF_INET sockets:
      struct sockaddr_in {
        short            sin_family;   // e.g. AF_INET, AF_INET6
        unsigned short   sin_port;     // e.g. htons(3490)
        struct in_addr   sin_addr;     // see struct in_addr, below
        char             sin_zero[8];  // zero this if you want to
      };
      struct in_addr {
        unsigned long s_addr;          // load with inet_pton()
      };
IPv6 AF_INET6 sockets:
      struct sockaddr_in6 {
        u_int16_t       sin6_family;   // address family, AF_INET6
        u_int16_t       sin6_port;     // port number, Network Byte Order
        u_int32_t       sin6_flowinfo; // IPv6 flow information
        struct in6_addr sin6_addr;     // IPv6 address
        u_int32_t       sin6_scope_id; // Scope ID
      };
      struct in6_addr {
          unsigned char   s6_addr[16];   // load with inet_pton()
      };
  

Definition at line 248 of file rlsocket.h.


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