ASSA::IPv4Socket Class Reference

#include <IPv4Socket.h>

Inheritance diagram for ASSA::IPv4Socket:

Inheritance graph
[legend]
Collaboration diagram for ASSA::IPv4Socket:

Collaboration graph
[legend]
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.

Detailed Description

Definition at line 25 of file IPv4Socket.h.


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::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, ASSA::Address::getAddress(), getDomain(), ASSA::Address::getLength(), 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(), 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(), connect(), 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(), ASSA::Address::getAddress(), getDomain(), ASSA::Address::getLength(), ASSA::is_valid_handler(), open(), ASSA::SOCK, ASSA::SOCKTRACE, and trace_with_mask.

Referenced by close().

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_
[virtual]
 

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.

Reimplemented from ASSA::Socket.

Definition at line 230 of file IPv4Socket.cpp.

References ASSA::is_valid_handler(), m_rdbuf, ASSA::Streambuf::sbumpc(), 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_
[virtual]
 

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

Reimplemented from ASSA::Socket.

Definition at line 293 of file IPv4Socket.cpp.

References ASSA::is_valid_handler(), m_rdbuf, ASSA::SOCKTRACE, ASSA::Streambuf::sputc(), 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 Sun Aug 13 15:08:20 2006 for libassa by  doxygen 1.4.6