#include <IPv4Socket.h>
Inheritance diagram for ASSA::IPv4Socket:
Public Member Functions | |
IPv4Socket () | |
Default constructor. | |
IPv4Socket (const int fd_) | |
Constructor from file descriptor. | |
~IPv4Socket () | |
Destructor will close connection. | |
IPv4Socket * | clone () 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. | |
IPv4Socket * | accept () |
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. | |
const int | getHandler () const |
Get socket file descriptor. | |
const int | getDomain () const |
Get socket domain type. | |
virtual Streambuf * | rdbuf () |
Return a pointer to the Socketbuf associated with the stream. | |
virtual Streambuf * | rdbuf (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 &) | |
IPv4Socket & | operator= (const IPv4Socket &) |
Private Attributes | |
char * | m_path |
Path of UNIX domain socket. | |
Streambuf * | m_rdbuf |
Socketbuf. |
Definition at line 25 of file IPv4Socket.h.
|
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 }
|
|
Constructor from file descriptor.
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 trace_with_mask("IPv4Socket::IPv4Socket(fd_)",SOCKTRACE); 00043 00044 m_fd = fd_; 00045 }
|
|
Destructor will close connection.
Definition at line 48 of file IPv4Socket.h. References close(), m_rdbuf, ASSA::SOCKTRACE, and trace_with_mask. 00048 { 00049 trace_with_mask("IPv4Socket::~IPv4Socket",SOCKTRACE); 00050 this->close (); 00051 00052 if (m_rdbuf != 0) { 00053 delete m_rdbuf; 00054 } 00055 }
|
|
|
|
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.
Definition at line 146 of file IPv4Socket.cpp. References ASSA::Socket::clear(), close(), DL, EL, ASSA::ERROR, getDomain(), IPv4Socket(), ASSA::Socket::m_fd, ASSA::Socket::nonblocking, ASSA::SOCK, ASSA::SOCKTRACE, trace_with_mask, and ASSA::Socket::turnOptionOn(). 00147 { 00148 /* 00149 Here's interesting spot - because accept() suppose to work 00150 both for INET and UNIX domain socket addresses, we have to 00151 allocate enough space and pass exact size of the address type 00152 expected. 00153 00154 Otherwise, if we use, for example, struct sockaddr_un as max. 00155 possible, and accept returns struct sockaddr_in, we can cast 00156 back to struct sockaddr_in, but internally address data members 00157 are not guaranteed to be aligned correctly!!! 00158 */ 00159 trace_with_mask("IPv4Socket::accept",SOCKTRACE); 00160 00161 socklen_t length = 0; 00162 int new_fd = -1; 00163 SA* remote_address = NULL; 00164 00165 if ( getDomain() == AF_UNIX ) { 00166 length = sizeof(struct sockaddr_in); 00167 remote_address = (SA*) new SA_IN; 00168 } 00169 else { 00170 remote_address = (SA*) new SA_UN; 00171 length = sizeof(struct sockaddr_un); 00172 } 00173 memset(remote_address, 0, length); 00174 00175 #ifndef __CYGWIN32__ 00176 new_fd = ::accept(m_fd, remote_address, &length); 00177 #else 00178 new_fd = ::accept(m_fd, remote_address, (int*)&length); 00179 #endif 00180 00181 if ( new_fd < 0 ) { 00182 EL((ERROR,"OS::accept() failed\n")); 00183 close(); 00184 return NULL; 00185 } 00186 if (length == sizeof(SA_IN)) { 00187 SA_IN* sa_in = (SA_IN*) remote_address; 00188 00189 DL((SOCK,"Accepted new TCP connection from Addr %s, port %d\n", 00190 inet_ntoa(sa_in->sin_addr), ntohs( sa_in->sin_port))); 00191 } 00192 else { 00193 SA_UN* sa_un = (SA_UN*) remote_address; 00194 DL((SOCK,"Accepted new UNIX connection from %s\n", 00195 sa_un->sun_path)); 00196 } 00197 delete remote_address; 00198 00199 IPv4Socket* s = new IPv4Socket (new_fd); 00200 s->clear (); 00201 s->turnOptionOn (Socket::nonblocking); 00202 return s; 00203 }
|
|
Server binds listening socket to its local well-known port. This call should follow the call to open() and precede the call to accept().
Implements ASSA::Socket. Definition at line 109 of file IPv4Socket.cpp. References Assure_return, EL, ASSA::Socket::failbit, ASSA::Address::getAddress(), getDomain(), ASSA::Address::getLength(), ASSA::Socket::m_fd, m_path, ASSA::Socket::reuseaddr, ASSA::Socket::setstate(), ASSA::SOCK, ASSA::SOCKTRACE, trace_with_mask, and ASSA::Socket::turnOptionOn(). 00110 { 00111 trace_with_mask("IPv4Socket::bind",SOCKTRACE); 00112 00113 // if UNIX domain, save the path 00114 if ( getDomain() == AF_UNIX ) { 00115 char* p = ((SA_UN *) addr_.getAddress())->sun_path; 00116 m_path = new char[strlen(p)+1]; 00117 strcpy(m_path, p); 00118 struct stat sb; 00119 00120 if (stat (m_path, &sb) == 0) { 00121 if ( S_ISSOCK(sb.st_mode) || S_ISFIFO(sb.st_mode) ) { 00122 unlink(m_path); 00123 } 00124 } 00125 } 00126 /*--- 00127 From Stevens, Ch 7.5 (p.196): 00128 "Set the SO_REUSEADDR socket option before calling bind(2) 00129 in all TCP servers." 00130 ---*/ 00131 Assure_return ( turnOptionOn (reuseaddr) ); 00132 00133 int rt = ::bind(m_fd, addr_.getAddress(), addr_.getLength()); 00134 00135 if ( rt < 0) { 00136 EL((SOCK,"::bind() FD: %d failed\n",m_fd)); 00137 setstate (Socket::failbit); 00138 return (false); 00139 } 00140 Assure_return ( (::listen(m_fd, 5) == 0) ); 00141 return (true); 00142 }
|
|
"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 300 of file IPv4Socket.cpp. References ASSA::Socket::clear(), DL, ASSA::Socket::failbit, ASSA::Socket::good(), ASSA::Streambuf::in_avail(), IPv4Socket(), ASSA::Socket::m_fd, m_rdbuf, ASSA::Socket::setstate(), ASSA::SOCK, ASSA::SOCKTRACE, and trace_with_mask. 00301 { 00302 const char self[] = "IPv4Socket::clone"; 00303 trace_with_mask(self,SOCKTRACE); 00304 00305 int nfd = dup (m_fd); 00306 00307 IPv4Socket* s = new IPv4Socket (nfd); 00308 00309 DL((SOCK,"Original socket has %d bytes in its get_area\n", 00310 m_rdbuf->in_avail ())); 00311 00312 if (nfd < 0 || !good ()) { 00313 s->setstate (Socket::failbit); 00314 } 00315 else { 00316 s->clear (); 00317 } 00318 return s; 00319 }
|
|
Close socket connection.
Implements ASSA::Socket. Definition at line 54 of file IPv4Socket.cpp. References connect(), DL, ASSA::Socket::failbit, ASSA::Socket::flush(), ASSA::Streambuf::in_avail(), 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(). 00055 { 00056 trace_with_mask("IPv4Socket::close()",SOCKTRACE); 00057 00058 if (m_fd >= 0) { 00059 DL((SOCK,"Closed FD: %d\n",m_fd)); 00060 00061 /*--- Flush data in output stream buffer ---*/ 00062 flush (); 00063 ::close(m_fd); 00064 setstate (Socket::failbit); 00065 m_fd = -1; 00066 00067 /*--- 00068 Socket can be re-opened in the future. 00069 If there is some bytes left in it since last read(2), 00070 clean them up. 00071 ---*/ 00072 00073 if (m_rdbuf && m_rdbuf->in_avail ()) { 00074 for (int c; (c=m_rdbuf->sbumpc ()) != EOF;) { } 00075 } 00076 } 00077 return (true); 00078 }
|
|
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.
Reimplemented from ASSA::Socket. Definition at line 82 of file IPv4Socket.cpp. References ASSA::Socket::clear(), DL, EL, ASSA::Address::getAddress(), getDomain(), ASSA::Address::getLength(), ASSA::Socket::m_fd, open(), ASSA::SOCK, ASSA::SOCKTRACE, and trace_with_mask. Referenced by close(). 00083 { 00084 trace_with_mask("IPv4Socket::connect()",SOCKTRACE); 00085 00086 if (m_fd < 0 && open (getDomain()) == false) { 00087 return false; 00088 } 00089 00090 int ret = ::connect (m_fd, 00091 (SA*) his_address_.getAddress(), 00092 his_address_.getLength()); 00093 if (ret < 0) { 00094 if (errno == EINPROGRESS) { // is it ASYNC connect in progress? 00095 DL((SOCK,"FD: %d OS::connect() error\n",m_fd)); 00096 } 00097 else { 00098 EL((SOCK,"FD: %d OS::connect() error\n",m_fd)); 00099 } 00100 return (false); 00101 } 00102 clear (); 00103 DL((SOCK,"Connection opened on FD: %d\n", m_fd)); 00104 return (true); 00105 }
|
|
Get socket domain type.
Implements ASSA::Socket. Definition at line 136 of file IPv4Socket.h. References ASSA::Socket::m_type. Referenced by accept(), bind(), and connect(). 00136 { return m_type; }
|
|
Get socket file descriptor.
Implements ASSA::Socket. Definition at line 133 of file IPv4Socket.h. References ASSA::Socket::m_fd. 00133 { return m_fd; }
|
|
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 160 of file IPv4Socket.h. References ASSA::Streambuf::in_avail(), and m_rdbuf. 00160 { return m_rdbuf->in_avail (); }
|
|
Create socket. Socket domain type is specified as AF_INET for internet socket and AF_UNIX for UNIX domain socket (full duplex pipe).
Implements ASSA::Socket. Definition at line 36 of file IPv4Socket.cpp. References ASSA::Socket::clear(), EL, ASSA::ERROR, ASSA::Socket::failbit, ASSA::Socket::m_fd, ASSA::Socket::m_type, ASSA::Socket::nonblocking, ASSA::Socket::setstate(), ASSA::SOCKTRACE, trace_with_mask, and ASSA::Socket::turnOptionOn(). Referenced by connect(). 00037 { 00038 trace_with_mask("IPv4Socket::open",SOCKTRACE); 00039 00040 m_type = domain_; 00041 m_fd = ::socket(domain_, SOCK_STREAM, 0); 00042 if (m_fd < 0) { 00043 EL((ERROR,"OS::socket() error\n")); 00044 setstate (Socket::failbit); 00045 return (false); 00046 } 00047 clear (); 00048 turnOptionOn (Socket::nonblocking); 00049 return (true); 00050 }
|
|
|
|
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). Reimplemented from ASSA::Socket. Definition at line 21 of file IPv4Socket.cpp. References m_rdbuf, ASSA::SOCKTRACE, and trace_with_mask. 00022 { 00023 trace_with_mask("IPv4Socket::rdbuf(sb_)",SOCKTRACE); 00024 00025 if (sb_ == 0 || sb_ == m_rdbuf) { 00026 return (sb_); 00027 } 00028 Streambuf* old = m_rdbuf; 00029 m_rdbuf = sb_; 00030 return (old); 00031 }
|
|
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 144 of file IPv4Socket.h. References m_rdbuf. 00144 { return m_rdbuf; }
|
|
Read packet of specified size and save it to the given buffer.
Reimplemented from ASSA::Socket. Definition at line 207 of file IPv4Socket.cpp. References ASSA::Socket::m_fd, m_rdbuf, ASSA::Streambuf::sbumpc(), ASSA::SOCKTRACE, trace_with_mask, and ASSA::Streambuf::unbuffered(). 00208 { 00209 trace_with_mask("IPv4Socket::read",SOCKTRACE); 00210 00211 register int len; 00212 register int sz = size_; 00213 char* tmp = packet_; 00214 00215 if (m_fd < 0) return -1; 00216 00217 len = 0; 00218 if (m_rdbuf->unbuffered ()) { 00219 /* 00220 --- This needs to be redesigned --- 00221 I should read a character at a time in loop, 00222 until I get all characters, or EWOULDBLOCK or EOF. 00223 If ::read() returns 0 or -1, it will be converted 00224 by sbumpc() into EOF. Otherwise, sbumpc() returns 00225 character read. Is this the right thing here to do? 00226 */ 00227 if ((len = m_rdbuf->sbumpc ()) >= 0) { 00228 *tmp = len; 00229 len = 1; 00230 } 00231 } 00232 else { 00233 len = m_rdbuf->sgetn (tmp, sz); 00234 } 00235 if (len == -1) { 00236 /* 00237 Non-blocking socket delivered partial packet. 00238 */ 00239 if (errno != EWOULDBLOCK) { 00240 EL((ERROR,"::read(fd = %d) \n",m_fd)); 00241 setstate (Socket::failbit); 00242 } 00243 return len; 00244 } 00245 tmp += len; 00246 sz -= len; 00247 00248 if ((size_ - sz) == 0) 00249 { 00250 DL((SOCK,"Peer has dropped connection FD: %d\n",m_fd)); 00251 setstate (Socket::failbit | Socket::eofbit); 00252 return 0; 00253 } 00254 00255 DL((SOCKTRACE,"==> FD: %d Received %d bytes\n", m_fd, size_ - sz)); 00256 MemDump::dump_to_log (SOCKTRACE, "Data received:", packet_, size_ - sz); 00257 00258 /* 00259 Return number of bytes read. If all requested bytes have been 00260 read, then sz is 0 and size_ is returned. If sz != 0, then 00261 writer has sent us a partial packet. 00262 */ 00263 return (size_ - sz); 00264 }
|
|
Perform blocking write by writing packet of specified size.
Reimplemented from ASSA::Socket. Definition at line 268 of file IPv4Socket.cpp. References ASSA::Socket::m_fd, m_rdbuf, ASSA::SOCKTRACE, ASSA::Streambuf::sputc(), trace_with_mask, and ASSA::Streambuf::unbuffered(). 00269 { 00270 trace_with_mask("IPv4Socket::write()",SOCKTRACE); 00271 00272 register int ret = 0; 00273 00274 if (m_fd < 0) return -1; 00275 00276 if (m_rdbuf->unbuffered ()) { 00277 register int wlen = size_; 00278 register char* p = (char*) packet_; 00279 00280 while (wlen-- > 0) { 00281 if (m_rdbuf->sputc (*p++) == EOF) { 00282 return (EOF); 00283 } 00284 } 00285 ret = p - packet_; 00286 } 00287 else 00288 ret = m_rdbuf->sputn ((char*) packet_, size_); 00289 00290 if (ret > 0) { 00291 DL((SOCK,"<= FD: %d Wrote %d bytes (requested %d bytes)\n", 00292 m_fd, ret, size_)); 00293 MemDump::dump_to_log (SOCK, "Data written", (char*)packet_, ret); 00294 } 00295 return ret; 00296 }
|
|
Path of UNIX domain socket.
Definition at line 171 of file IPv4Socket.h. Referenced by bind(). |
|
Definition at line 174 of file IPv4Socket.h. Referenced by clone(), close(), in_avail(), rdbuf(), read(), write(), and ~IPv4Socket(). |
|
Maximum TCP data frame (no options).
Definition at line 29 of file IPv4Socket.h. |