Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

ASSA::IPv4Socket Class Reference

#include <IPv4Socket.h>

Inheritance diagram for ASSA::IPv4Socket:

ASSA::Socket List of all members.

Public Member Functions

 IPv4Socket ()
 Default constructor.
 IPv4Socket (const handler_t fd_)
 Constructor from file descriptor.
 ~IPv4Socket ()
 Destructor will close connection.
IPv4Socketclone () const
 "Virtual constructor".
bool open (const int domain_)
 Create socket.
bool close ()
 Close socket connection.
bool connect (const Address &address_)
 Client makes connection with the server at address_.
virtual bool bind (const Address &my_address_)
 Server binds listening socket to its local well-known port.
IPv4Socketaccept ()
 Accept connection on the listening socket.
int read (char *buf_, const unsigned int size_)
 Read packet of specified size and save it to the given buffer.
int write (const char *buf_, const unsigned int size_)
 Perform blocking write by writing packet of specified size.
handler_t getHandler () const
 Get socket file descriptor.
const int getDomain () const
 Get socket domain type.
virtual Streambufrdbuf ()
 Return a pointer to the Socketbuf associated with the stream.
virtual Streambufrdbuf (Streambuf *sb_)
 Set new Socketbuf for internal IO buffering.
virtual int in_avail () const
 This function returns the number of characters immediately available in the get area of the underlying Socketbuf buffer without making a system call if Socket is doing buffering I/O.

Static Public Attributes

static const int MAXTCPBUFSZ
 Maximum TCP data frame (no options).

Private Member Functions

 IPv4Socket (const IPv4Socket &)
IPv4Socketoperator= (const IPv4Socket &)

Private Attributes

char * m_path
 Path of UNIX domain socket.
Streambufm_rdbuf
 Socketbuf.

Constructor & Destructor Documentation

ASSA::IPv4Socket::IPv4Socket  )  [inline]
 

Default constructor.

Definition at line 32 of file IPv4Socket.h.

References ASSA::SOCKTRACE, and trace_with_mask.

Referenced by accept(), and clone().

00033         : m_path (0), m_rdbuf (new Socketbuf (this)) {
00034         trace_with_mask("IPv4Socket::IPv4Socket()",SOCKTRACE);
00035     }

ASSA::IPv4Socket::IPv4Socket const handler_t  fd_  )  [inline]
 

Constructor from file descriptor.

Parameters:
fd_ file descriptor to use

Definition at line 40 of file IPv4Socket.h.

References ASSA::Socket::m_fd, ASSA::SOCKTRACE, and trace_with_mask.

00041         : m_path (0), m_rdbuf (new Socketbuf (this))
00042     {
00043         trace_with_mask("IPv4Socket::IPv4Socket(fd_)",SOCKTRACE);
00044 
00045         m_fd = fd_;             // inherited from the parent class
00046     }

ASSA::IPv4Socket::~IPv4Socket  )  [inline]
 

Destructor will close connection.

Definition at line 49 of file IPv4Socket.h.

References close(), m_rdbuf, ASSA::SOCKTRACE, and trace_with_mask.

00050     {
00051         trace_with_mask("IPv4Socket::~IPv4Socket",SOCKTRACE);
00052         this->close ();
00053 
00054         if (m_rdbuf != 0) {
00055             delete m_rdbuf;
00056         }
00057     }

ASSA::IPv4Socket::IPv4Socket const IPv4Socket  )  [private]
 


Member Function Documentation

IPv4Socket * IPv4Socket::accept  ) 
 

Accept connection on the listening socket.

Returned is a COMPLETED connection (meaning that socket pair is ready for data transfer and doesn't need call to ::open()). This method will block waiting on connection to come if there is no connection requests waiting on the listenning socket queue. To avoid blocking, use ::select() first.

Returns:
newly created connected socket to the client, or 0 if error.

Definition at line 176 of file IPv4Socket.cpp.

References ASSA::ASSAERR, ASSA::Socket::clear(), close(), ASSA::disable_handler(), DL, EL, getDomain(), IPv4Socket(), ASSA::is_valid_handler(), ASSA::Socket::m_fd, ASSA::Socket::nonblocking, ASSA::SOCK, ASSA::SOCKTRACE, trace_with_mask, and ASSA::Socket::turnOptionOn().

00177 {
00178     trace_with_mask("IPv4Socket::accept",SOCKTRACE);
00179 
00180     socklen_t length = 0;
00181     SA*       remote_address = NULL;
00182     handler_t new_fd;
00183 
00184     disable_handler (new_fd);
00185 
00186     if ( getDomain() == AF_UNIX ) {
00187         length = sizeof(struct sockaddr_in);
00188         remote_address = (SA*) new SA_IN;
00189     }
00190     else   /* AF_INET */
00191     { 
00192         remote_address = (SA*) new SA_UN;
00193         length = sizeof(struct sockaddr_un);
00194     }
00195     memset(remote_address, 0, length);
00196 
00197 #if !defined (_CYGWIN32__)
00198     new_fd = ::accept(m_fd, remote_address, &length);
00199 #else
00200     new_fd = ::accept(m_fd, remote_address, (int*)&length);
00201 #endif
00202     
00203     if (!is_valid_handler (new_fd)) {
00204         EL((ASSAERR,"::accept() failed (new_fd=%d)\n", new_fd));
00205         close();
00206         return NULL;
00207     }
00208     if (length == sizeof(SA_IN)) {
00209         SA_IN* sa_in = (SA_IN*) remote_address;
00210 
00211         DL((SOCK,"Accepted new TCP connection from Addr %s, port %d\n", 
00212             inet_ntoa(sa_in->sin_addr), ntohs( sa_in->sin_port)));
00213     }
00214     else {
00215 #if !defined(WIN32)
00216         SA_UN* sa_un = (SA_UN*) remote_address;
00217         DL((SOCK,"Accepted new UNIX connection from %s\n", sa_un->sun_path));
00218 #endif
00219     }
00220     delete remote_address;
00221 
00222     IPv4Socket* s = new IPv4Socket (new_fd);
00223     s->clear ();
00224     s->turnOptionOn (Socket::nonblocking);
00225     return s;
00226 }

bool IPv4Socket::bind const Address my_address_  )  [virtual]
 

Server binds listening socket to its local well-known port.

This call should follow the call to open() and precede the call to accept().

Parameters:
my_address_ address to bind to
Returns:
true if success, false otherwise

Implements ASSA::Socket.

Definition at line 123 of file IPv4Socket.cpp.

References Assure_return, EL, ASSA::Socket::failbit, getDomain(), ASSA::Socket::m_fd, m_path, ASSA::Socket::reuseaddr, ASSA::Socket::setstate(), ASSA::SOCK, ASSA::SOCKTRACE, trace_with_mask, and ASSA::Socket::turnOptionOn().

00124 {
00125     trace_with_mask("IPv4Socket::bind",SOCKTRACE);
00126 
00127 #if !defined(WIN32)
00128 
00131     if ( getDomain() == AF_UNIX ) {
00132         char* p = ((SA_UN *) addr_.getAddress())->sun_path;
00133         m_path = new char[strlen(p)+1];
00134         strcpy(m_path, p);
00135         struct stat sb;
00136 
00137         if (stat (m_path, &sb) == 0) {
00138             if ( S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode) ) {
00139                 unlink(m_path);
00140             }
00141         }
00142     }
00143 #endif
00144 
00145     /*---
00146       From Stevens, Ch 7.5 (p.196):
00147       "Set the SO_REUSEADDR socket option before calling bind(2)
00148       in all TCP servers."
00149       ---*/
00150     Assure_return ( turnOptionOn (reuseaddr) );
00151 
00152     int rt = ::bind(m_fd, addr_.getAddress(), addr_.getLength());
00153 
00154     if ( rt < 0) {
00155         EL((SOCK,"::bind() FD: %d failed\n",m_fd));
00156         setstate (Socket::failbit);
00157         return (false);
00158     }
00159     Assure_return ( (::listen(m_fd, 5) == 0) );
00160     return (true);
00161 }

IPv4Socket * IPv4Socket::clone  )  const
 

"Virtual constructor".

clone() function creates an exact copy of Socket by dup(2)-ing file descriptor and copying Socket's internal state.

Definition at line 329 of file IPv4Socket.cpp.

References ASSA::Socket::clear(), DL, ASSA::Socket::failbit, ASSA::Socket::good(), ASSA::Streambuf::in_avail(), IPv4Socket(), ASSA::is_valid_handler(), ASSA::Socket::m_fd, m_rdbuf, ASSA::Socket::setstate(), ASSA::SOCK, ASSA::SOCKTRACE, and trace_with_mask.

00330 {
00331     const char self[] = "IPv4Socket::clone"; 
00332     trace_with_mask(self,SOCKTRACE);
00333 
00334     handler_t nfd = dup (m_fd);
00335     IPv4Socket* s = new IPv4Socket (nfd);
00336 
00337     DL((SOCK,"Original socket has %d bytes in its get_area\n",
00338         m_rdbuf->in_avail ()));
00339 
00340     if (!is_valid_handler (nfd) || !good ()) {
00341         s->setstate (Socket::failbit);
00342     }
00343     else {
00344         s->clear ();
00345     }
00346 
00347     return s;
00348 }

bool IPv4Socket::close  )  [virtual]
 

Close socket connection.

Returns:
true if success, fail if call to ::close() failed.

Implements ASSA::Socket.

Definition at line 65 of file IPv4Socket.cpp.

References ASSA::Socket::close_handler(), DL, ASSA::Socket::failbit, ASSA::Socket::flush(), ASSA::Streambuf::in_avail(), ASSA::is_valid_handler(), ASSA::Socket::m_fd, m_rdbuf, ASSA::Streambuf::sbumpc(), ASSA::Socket::setstate(), ASSA::SOCK, ASSA::SOCKTRACE, and trace_with_mask.

Referenced by accept(), and ~IPv4Socket().

00066 {
00067     trace_with_mask("IPv4Socket::close()",SOCKTRACE);
00068 
00069     if (is_valid_handler (m_fd)) {
00070         DL((SOCK,"Closed FD: %d\n",m_fd));
00071 
00072         /*--- Flush data in output stream buffer ---*/
00073         flush ();
00074         close_handler(m_fd);
00075         setstate (Socket::failbit);
00076 
00077         /*--- 
00078           Socket can be re-opened in the future.
00079           If there is some bytes left in it since last read(2),
00080           clean them up.
00081           ---*/
00082 
00083         if (m_rdbuf && m_rdbuf->in_avail ()) {
00084             for (int c; (c=m_rdbuf->sbumpc ()) != EOF;) { }
00085         }
00086     }
00087     return (true);
00088 }

bool IPv4Socket::connect const Address address_  )  [virtual]
 

Client makes connection with the server at address_.

If socket is set to non-blocking mode, most likely connect() would return false with errno set to EINPROGRESS. See connect(2) manpage for details.

Parameters:
address_ peer address to connect with
Returns:
true for success, false for error

Reimplemented from ASSA::Socket.

Definition at line 92 of file IPv4Socket.cpp.

References ASSA::Socket::clear(), DL, EL, ASSA::get_errno(), getDomain(), ASSA::is_valid_handler(), ASSA::Socket::m_fd, open(), ASSA::SOCK, ASSA::SOCKTRACE, and trace_with_mask.

00093 {
00094     trace_with_mask("IPv4Socket::connect()",SOCKTRACE);
00095 
00096     if (!is_valid_handler (m_fd) && open (getDomain()) == false) {
00097         return false;
00098     }
00099 
00100     int ret = ::connect (m_fd, 
00101                          (SA*) his_address_.getAddress(),
00102                          his_address_.getLength());
00103     if (ret < 0) 
00104     {
00105         int e = get_errno ();   // is ASYNC connect in progress?
00106         if (e == EINPROGRESS || e == EWOULDBLOCK) { 
00107             DL((SOCK,"FD: %d OS::connect() error\n",m_fd));
00108         }
00109         else {
00110             EL((SOCK,"FD: %d OS::connect() error\n",m_fd));
00111         }
00112         return (false);
00113     }
00114 
00115     clear ();
00116 
00117     DL((SOCK,"Connection opened on FD: %d\n", m_fd));
00118     return (true);
00119 }

const int ASSA::IPv4Socket::getDomain  )  const [inline, virtual]
 

Get socket domain type.

Implements ASSA::Socket.

Definition at line 138 of file IPv4Socket.h.

References ASSA::Socket::m_type.

Referenced by accept(), bind(), and connect().

00138 { return m_type; }

handler_t ASSA::IPv4Socket::getHandler  )  const [inline, virtual]
 

Get socket file descriptor.

Implements ASSA::Socket.

Definition at line 135 of file IPv4Socket.h.

References ASSA::Socket::m_fd.

00135 { return m_fd; }

virtual int ASSA::IPv4Socket::in_avail  )  const [inline, virtual]
 

This function returns the number of characters immediately available in the get area of the underlying Socketbuf buffer without making a system call if Socket is doing buffering I/O.

Implements ASSA::Socket.

Definition at line 162 of file IPv4Socket.h.

References ASSA::Streambuf::in_avail(), and m_rdbuf.

00162 { return m_rdbuf->in_avail (); }

bool IPv4Socket::open const int  domain_  )  [virtual]
 

Create socket.

Socket domain type is specified as AF_INET for internet socket and AF_UNIX for UNIX domain socket (full duplex pipe).

Parameters:
domain_ domain
Returns:
true if socket is created successfully, false otherwise

Implements ASSA::Socket.

Definition at line 41 of file IPv4Socket.cpp.

References ASSA::ASSAERR, ASSA::Socket::clear(), ASSA::disable_handler(), DL, EL, ASSA::Socket::failbit, ASSA::is_valid_handler(), ASSA::Socket::m_fd, ASSA::Socket::m_type, ASSA::Socket::nonblocking, ASSA::Socket::setstate(), ASSA::SOCK, ASSA::SOCKTRACE, trace_with_mask, and ASSA::Socket::turnOptionOn().

Referenced by connect().

00042 {
00043     trace_with_mask("IPv4Socket::open",SOCKTRACE);
00044     
00045     m_type = domain_;
00046 
00047     m_fd = ::socket(domain_, SOCK_STREAM, 0);
00048 
00049     if (!is_valid_handler (m_fd)) {
00050         EL((ASSAERR,"OS::socket() error: m_fd = %d\n", m_fd));
00051         setstate (Socket::failbit);
00052         disable_handler (m_fd);
00053         return (false);
00054     }
00055     DL ((SOCK,"domain = %d, m_fd = %d\n", domain_, m_fd));
00056 
00057     clear ();
00058     turnOptionOn (Socket::nonblocking);
00059 
00060     return (true);
00061 }

IPv4Socket& ASSA::IPv4Socket::operator= const IPv4Socket  )  [private]
 

Streambuf * IPv4Socket::rdbuf Streambuf sb_  )  [virtual]
 

Set new Socketbuf for internal IO buffering.

IPv4Socket object assumes full ownership of the memory pointed by sb_ (it will be release when ~IPv4Socket destructor is called).

Returns:
Old Socketbuf object or sb_ if it is either NULL or matches old Socketbuf object.

Reimplemented from ASSA::Socket.

Definition at line 26 of file IPv4Socket.cpp.

References m_rdbuf, ASSA::SOCKTRACE, and trace_with_mask.

00027 { 
00028     trace_with_mask("IPv4Socket::rdbuf(sb_)",SOCKTRACE);
00029 
00030     if (sb_ == 0 || sb_ == m_rdbuf) {
00031         return (sb_);
00032     }
00033     Streambuf* old = m_rdbuf;
00034     m_rdbuf = sb_;
00035     return (old);
00036 }

virtual Streambuf* ASSA::IPv4Socket::rdbuf  )  [inline, virtual]
 

Return a pointer to the Socketbuf associated with the stream.

This is part of the construction of a stream, and the buffer class object is not normally changed. This function may be used to get at Socketbuf functionality directly, given a Socket object.

Reimplemented from ASSA::Socket.

Definition at line 146 of file IPv4Socket.h.

References m_rdbuf.

00146 { return m_rdbuf; }

int IPv4Socket::read char *  buf_,
const unsigned int  size_
 

Read packet of specified size and save it to the given buffer.

Parameters:
buf_ buffer where packet will be stored
size_ size of the packet to expect
Returns:
number of bytes read or -1 on error indicating the reason in errno. 0 is returned if remote host closed its socket connection.

Definition at line 230 of file IPv4Socket.cpp.

References ASSA::ASSAERR, DL, ASSA::MemDump::dump_to_log(), EL, ASSA::Socket::eofbit, ASSA::Socket::failbit, ASSA::get_errno(), ASSA::is_valid_handler(), ASSA::Socket::m_fd, m_rdbuf, ASSA::Streambuf::sbumpc(), ASSA::Socket::setstate(), ASSA::Streambuf::sgetn(), ASSA::SOCK, ASSA::SOCKTRACE, trace_with_mask, and ASSA::Streambuf::unbuffered().

00231 {
00232     trace_with_mask("IPv4Socket::read",SOCKTRACE);
00233 
00234     register int len;
00235     register int sz = size_;
00236     char* tmp = packet_;
00237     
00238     if (!is_valid_handler (m_fd) < 0) {
00239         return -1;
00240     }
00241 
00242     len = 0;
00243     if (m_rdbuf->unbuffered ()) { 
00244         /*
00245           --- This needs to be redesigned ---
00246           I should read a character at a time in loop,
00247           until I get all characters, or EWOULDBLOCK or EOF.
00248           If ::read() returns 0 or -1, it will be converted
00249           by sbumpc() into EOF. Otherwise, sbumpc() returns
00250           character read. Is this the right thing here to do? 
00251         */
00252         if ((len = m_rdbuf->sbumpc ()) >= 0) {
00253             *tmp = len; 
00254             len = 1;
00255         }
00256     }
00257     else {
00258         len = m_rdbuf->sgetn (tmp, sz);
00259     }
00260     if (len == -1) 
00261     {
00264         if (get_errno () != EWOULDBLOCK) {
00265             EL((ASSAERR,"::read (fd=%d) failed.\n",m_fd));
00266             setstate (Socket::failbit);
00267         }
00268         return len;
00269     }
00270     tmp += len;
00271     sz  -= len;
00272 
00273     if ((size_ - sz) == 0) 
00274     {
00275         DL((SOCK,"Peer has dropped connection FD: %d\n",m_fd));
00276         setstate (Socket::failbit | Socket::eofbit);
00277         return 0;
00278     }
00279 
00280     DL((SOCKTRACE,"==> FD: %d Received %d bytes\n", m_fd, size_ - sz));
00281     MemDump::dump_to_log (SOCKTRACE, "Data received:", packet_, size_ - sz);
00282 
00283     /*
00284       Return number of bytes read. If all requested bytes have been
00285       read, then sz is 0 and size_ is returned. If sz != 0, then
00286       writer has sent us a partial packet.
00287     */
00288     return (size_ - sz);        
00289 }

int IPv4Socket::write const char *  buf_,
const unsigned int  size_
 

Perform blocking write by writing packet of specified size.

Parameters:
buf_ buffer to send
size_ packet size
Returns:
number of bytes written or -1 for error

Definition at line 293 of file IPv4Socket.cpp.

References DL, ASSA::MemDump::dump_to_log(), ASSA::is_valid_handler(), ASSA::Socket::m_fd, m_rdbuf, ASSA::SOCK, ASSA::SOCKTRACE, ASSA::Streambuf::sputc(), ASSA::Streambuf::sputn(), trace_with_mask, and ASSA::Streambuf::unbuffered().

00294 {
00295     trace_with_mask("IPv4Socket::write()",SOCKTRACE);
00296 
00297     int ret = 0;
00298 
00299     if (!is_valid_handler (m_fd)) {
00300         return -1;
00301     }
00302 
00303     if (m_rdbuf->unbuffered ()) 
00304     {
00305         int wlen = size_;
00306         char* p = (char*) packet_;
00307 
00308         while (wlen-- > 0) {
00309             if (m_rdbuf->sputc (*p++) == EOF) {
00310                 return (EOF);
00311             }
00312         }
00313         ret = p - packet_;
00314     }
00315     else {
00316         ret = m_rdbuf->sputn ((char*) packet_, size_);
00317     }
00318 
00319     if (ret > 0) {
00320         DL((SOCK,"<= FD: %d Wrote %d bytes (requested %d bytes)\n",
00321             m_fd, ret, size_));
00322         MemDump::dump_to_log (SOCK, "Data written", (char*)packet_, ret);
00323     }
00324     return ret;
00325 }


Member Data Documentation

char* ASSA::IPv4Socket::m_path [private]
 

Path of UNIX domain socket.

Definition at line 173 of file IPv4Socket.h.

Referenced by bind().

Streambuf* ASSA::IPv4Socket::m_rdbuf [private]
 

Socketbuf.

Definition at line 176 of file IPv4Socket.h.

Referenced by clone(), close(), in_avail(), rdbuf(), read(), write(), and ~IPv4Socket().

const int ASSA::IPv4Socket::MAXTCPBUFSZ [static]
 

Maximum TCP data frame (no options).

Definition at line 29 of file IPv4Socket.h.


The documentation for this class was generated from the following files:
Generated on Mon Mar 26 22:47:36 2007 for libassa by  doxygen 1.4.2