libassa
3.5.0
|
00001 // -*- c++ -*- 00002 //------------------------------------------------------------------------------ 00003 // Socket.h 00004 //------------------------------------------------------------------------------ 00005 // Copyright (C) 1997-2002,2005 Vladislav Grinchenko 00006 // 00007 // This library is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Library General Public 00009 // License as published by the Free Software Foundation; either 00010 // version 2 of the License, or (at your option) any later version. 00011 //------------------------------------------------------------------------------ 00012 // 00013 // This class is a direct derivative from my Unix Network Programming 00014 // class work on generalizing object-oriented network interfaces. 00015 // 00016 //------------------------------------------------------------------------------ 00017 // Created: 03/22/1999 00018 //------------------------------------------------------------------------------ 00019 00020 #ifndef SOCKET_H 00021 #define SOCKET_H 00022 00023 #include <sys/stat.h> 00024 #include <sys/time.h> 00025 #include <limits.h> // for INT_MAX 00026 #include <stdio.h> // for EOF 00027 #include <sys/types.h> 00028 #include <unistd.h> 00029 #include <fcntl.h> // for fcntl(2) 00030 00031 #ifdef linux 00032 # include <sys/ioctl.h> // ioctl(2) 00033 #endif 00034 00035 #ifdef sun // ioctl(2) 00036 # include <unistd.h> 00037 # include <stropts.h> 00038 # include <sys/filio.h> 00039 #endif 00040 00041 #include "assa/Address.h" 00042 00052 #define BYTES_LEFT_IN_SOCKBUF(s) ((s).eof () ? -1 : (s).in_avail ()) 00053 00059 #define BYTES_LEFT_IN_SIN (cin.eof () ? -1 : cin.rdbuf ()->in_avail ()) 00060 00061 00062 namespace ASSA { 00063 00064 class Streambuf; // Forward declaration 00065 00071 class Socket { 00072 public: 00074 static const int PGSIZE; 00075 00080 enum io_state_t { 00081 goodbit = 0, 00082 eofbit = 1, 00084 failbit = 2, 00087 badbit = 4 00090 }; 00091 00092 typedef int iostate; 00093 typedef unsigned char IOState; 00094 00098 enum opt_t 00099 { 00100 reuseaddr, 00102 rcvlowat, 00108 sndlowat, 00115 nonblocking 00143 }; 00144 00146 Socket(); 00147 00149 virtual ~Socket(); 00150 00152 virtual bool open(const int domain_) =0; 00153 00155 virtual bool close() =0; 00156 00161 virtual bool connect (const Address& address_); 00162 00168 virtual bool bind (const Address& my_address_) =0; 00169 00175 virtual int write (const char* buf_, const u_int size_); 00176 00179 int getBytesAvail (void) const; 00180 00185 virtual int read (char* buf_, const u_int size_); 00186 00224 int ignore (int n_ = INT_MAX, int delim_ = EOF); 00225 00227 virtual handler_t getHandler() const = 0; 00228 00230 virtual const int getDomain() const = 0; 00231 00240 virtual Streambuf* rdbuf () { return 0; } 00241 00247 virtual Streambuf* rdbuf (Streambuf* /*sb_*/) { return 0; } 00248 00256 virtual int in_avail () const = 0; 00257 00264 virtual Socket& flush (); 00265 00270 bool turnOptionOn (opt_t opt_); 00271 00276 bool turnOptionOff (opt_t opt_); 00277 00284 bool setOption (opt_t opt_, int arg_); 00285 00291 int getOption (opt_t opt_) const; 00292 00294 operator void* () const; 00295 00297 bool operator! () const; 00298 00302 iostate rdstate () const { return m_state; } 00303 00305 void clear (iostate state_ = Socket::goodbit); 00306 00310 void setstate (iostate flag_); 00311 00315 bool good () const { return m_state == 0; } 00316 00321 bool eof () const { return m_state & Socket::eofbit; } 00322 00328 bool fail () const 00329 { 00330 return m_state & (Socket::failbit | Socket::badbit); 00331 } 00332 00337 bool bad () const { return m_state & Socket::badbit; } 00338 00340 void dumpState () const; 00341 00343 static size_t xdr_length (const std::string& s_) 00344 { 00345 return (4 + s_.length () + s_.length () % 4); 00346 } 00347 00349 Socket& operator>> (char& c); 00350 00352 Socket& operator>> (unsigned char& c_) 00353 { 00354 return operator>>((char&) c_); 00355 } 00356 00358 Socket& operator>> (signed char& c_) 00359 { 00360 return operator>>((char&) c_); 00361 } 00362 00364 Socket& operator>> (std::string& s_); 00365 00367 Socket& operator>> (short& n_); 00368 00370 Socket& operator>> (unsigned short& n_); 00371 00373 Socket& operator>> (int& n_); 00374 00376 Socket& operator>> (unsigned int& n_); 00377 00379 Socket& operator>> (long& n_); 00380 00382 Socket& operator>> (unsigned long& n_); 00383 00385 Socket& operator>> (float& n_); 00386 00388 Socket& operator>> (double& n_); 00389 00391 Socket& operator<< (char c); 00392 00394 Socket& operator<< (unsigned char c_) 00395 { 00396 return (*this) << (char) c_; 00397 } 00398 00400 Socket& operator<< (signed char c_) 00401 { 00402 return (*this) << (char) c_; 00403 } 00404 00406 Socket& operator<< (const std::string& s_); 00407 00409 Socket& operator<< (short n_); 00410 00412 Socket& operator<< (unsigned short n_); 00413 00415 Socket& operator<< (int n_); 00416 00418 Socket& operator<< (unsigned int n_); 00419 00421 Socket& operator<< (long n_); 00422 00424 Socket& operator<< (unsigned long n_); 00425 00427 Socket& operator<< (float n_); 00428 00430 Socket& operator<< (double n_); 00431 00433 Socket& operator<< (Socket& (*f) (Socket&)) 00434 { 00435 return (f (*this)); 00436 } 00437 00443 static bool is_little_endian (); 00444 00448 static void close_handler (handler_t& socket_) 00449 { 00450 #if defined (WIN32) 00451 closesocket (socket_); 00452 #else 00453 ::close (socket_); 00454 #endif 00455 disable_handler (socket_); 00456 } 00457 00460 static string decode_fcntl_flags (long mask_); 00461 00462 /*------------------------------------------------------------------ 00463 * Protected Members 00464 *------------------------------------------------------------------ 00465 */ 00466 protected: 00470 int set_option (int level_, int optname_, int val_); 00471 00475 int set_fd_options (long flags_); 00476 00480 int clear_fd_options (long flags_); 00481 00482 protected: 00485 handler_t m_fd; // u_int, INVALID_SOCKET=(SOCKET)(~0) 00486 00488 int m_type; 00489 00490 #if defined (WIN32) 00491 bool m_nonblocking; // We cannot retrieve the status of the 00492 // socket. So, we remember what it was instead. 00493 #endif 00494 00496 IOState m_state; 00497 00498 //------------------------------------------------------------------------------ 00499 // Inline functions 00500 //------------------------------------------------------------------------------ 00501 00502 private: 00509 Socket (const Socket&); 00510 Socket& operator= (const Socket&); 00511 }; 00512 00513 //------------------------------------------------------------------------------ 00514 // Inline functions 00515 //------------------------------------------------------------------------------ 00516 00517 inline 00518 Socket::Socket() 00519 : 00520 m_fd (BAD_HANDLER), 00521 m_type(0), 00522 #if defined (WIN32) 00523 m_nonblocking (false), 00524 #endif 00525 m_state(Socket::badbit) 00526 { 00527 trace_with_mask("Socket::Socket",SOCKTRACE); 00528 } 00529 00530 inline 00531 Socket::~Socket () 00532 { 00533 trace_with_mask("Socket::~Socket",SOCKTRACE); 00534 } 00535 00536 inline bool 00537 Socket::connect (const Address& /* address_ */) 00538 { 00539 trace_with_mask("Socket::connect",SOCKTRACE); 00540 return false; 00541 } 00542 00543 inline int 00544 Socket::write(const char* /*buf_*/, const u_int /*size_*/) 00545 { 00546 trace_with_mask("Socket::write",SOCKTRACE); 00547 return -1; 00548 } 00549 00550 inline int 00551 Socket::read(char* /*buf_*/, const u_int /*size_*/) 00552 { 00553 trace_with_mask("Socket::read()",SOCKTRACE); 00554 return -1; 00555 } 00556 00557 inline 00558 Socket::operator void*() const 00559 { 00560 return fail() ? (void *)0 : (void *)(-1); 00561 } 00562 00563 inline bool 00564 Socket::operator!() const 00565 { 00566 return fail(); 00567 } 00568 00569 00570 inline void 00571 Socket::clear(iostate state_) 00572 { 00573 m_state = is_valid_handler (m_fd) ? state_ : state_ | Socket::badbit; 00574 } 00575 00576 inline void 00577 Socket::setstate(iostate flag_) 00578 { 00579 m_state |= flag_; 00580 } 00581 00586 inline 00587 Socket& flush (Socket& os_) 00588 { 00589 os_.flush (); 00590 return (os_); 00591 } 00592 00601 inline 00602 Socket& endl (Socket& os_) 00603 { 00604 char c = '\n'; 00605 os_.write (&c, 1); 00606 os_.flush (); 00607 return (os_); 00608 } 00609 00621 inline 00622 Socket& ends (Socket& os_) 00623 { 00624 char c = '\0'; 00625 os_.write (&c, 1); 00626 return (os_); 00627 } 00628 00629 } // end namespace ASSA 00630 00631 #include "assa/Streambuf.h" 00632 00633 #endif // SOCKET_H 00634 00635 00636