ucommon
|
00001 // Copyright (C) 1999-2005 Open Source Telecom Corporation. 00002 // Copyright (C) 2006-2010 David Sugar, Tycho Softworks. 00003 // 00004 // This program is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 // 00018 // As a special exception, you may use this file as part of a free software 00019 // library without restriction. Specifically, if other files instantiate 00020 // templates or use macros or inline functions from this file, or you compile 00021 // this file and link it with other files to produce an executable, this 00022 // file does not by itself cause the resulting executable to be covered by 00023 // the GNU General Public License. This exception does not however 00024 // invalidate any other reasons why the executable file might be covered by 00025 // the GNU General Public License. 00026 // 00027 // This exception applies only to the code released under the name GNU 00028 // Common C++. If you copy code from other releases into a copy of GNU 00029 // Common C++, as the General Public License permits, the exception does 00030 // not apply to the code that you add in this way. To avoid misleading 00031 // anyone as to the status of such modified files, you must delete 00032 // this exception notice from them. 00033 // 00034 // If you write modifications of your own for GNU Common C++, it is your choice 00035 // whether to permit this exception to apply to your modifications. 00036 // If you do not wish that, delete this exception notice. 00037 // 00038 00044 #ifndef COMMONCPP_TCP_H_ 00045 #define COMMONCPP_TCP_H_ 00046 00047 #include <cstdio> 00048 00049 #ifndef COMMONCPP_CONFIG_H_ 00050 #include <commoncpp/config.h> 00051 #endif 00052 00053 #ifndef COMMONCPP_STRING_H_ 00054 #include <commoncpp/string.h> 00055 #endif 00056 00057 #ifndef COMMONCPP_ADDRESS_H_ 00058 #include <commoncpp/address.h> 00059 #endif 00060 00061 #ifndef COMMONCPP_SOCKET_H_ 00062 #include <commoncpp/socket.h> 00063 #endif 00064 00065 NAMESPACE_COMMONCPP 00066 00091 class __EXPORT TCPSocket : protected Socket 00092 { 00093 protected: 00094 int segsize; 00095 void setSegmentSize(unsigned mss); 00096 00097 public: 00109 virtual bool onAccept(const IPV4Host &ia, tpport_t port); 00110 00114 inline SOCKET getSocket(void) 00115 {return so;}; 00116 00120 inline int getSegmentSize(void) 00121 {return segsize;}; 00122 00135 TCPSocket(const IPV4Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536); 00136 00147 TCPSocket(const char *name, unsigned backlog = 5, unsigned mss = 536); 00148 00157 inline IPV4Host getRequest(tpport_t *port = NULL) const 00158 {return Socket::getIPV4Sender(port);} 00159 00163 void reject(void); 00164 00168 inline IPV4Host getLocal(tpport_t *port = NULL) const 00169 {return Socket::getIPV4Local(port);} 00170 00176 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */ 00177 {return Socket::isPending(Socket::pendingInput, timeout);} 00178 00182 virtual ~TCPSocket(); 00183 }; 00184 00185 #ifdef CCXX_IPV6 00186 00210 class __EXPORT TCPV6Socket : protected Socket 00211 { 00212 private: 00213 int segsize; 00214 void setSegmentSize(unsigned mss); 00215 00216 public: 00228 virtual bool onAccept(const IPV6Host &ia, tpport_t port); 00229 00233 inline SOCKET getSocket(void) 00234 {return so;}; 00235 00236 inline int getSegmentSize(void) 00237 {return segsize;}; 00238 00251 TCPV6Socket(const IPV6Address &bind, tpport_t port, unsigned backlog = 5, unsigned mss = 536); 00252 00263 TCPV6Socket(const char *name, unsigned backlog = 5, unsigned mss = 536); 00264 00273 inline IPV6Host getRequest(tpport_t *port = NULL) const 00274 {return Socket::getIPV6Sender(port);} 00275 00279 void reject(void); 00280 00284 inline IPV6Host getLocal(tpport_t *port = NULL) const 00285 {return Socket::getIPV6Local(port);} 00286 00292 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF) /* not const -- jfc */ 00293 {return Socket::isPending(Socket::pendingInput, timeout);} 00294 00298 virtual ~TCPV6Socket(); 00299 }; 00300 #endif 00301 00315 class __EXPORT TCPStream : protected std::streambuf, public Socket, public std::iostream 00316 { 00317 private: 00318 int doallocate(); 00319 00320 void segmentBuffering(unsigned mss); 00321 00322 friend TCPStream& crlf(TCPStream&); 00323 friend TCPStream& lfcr(TCPStream&); 00324 00325 // no copy constructor... 00326 TCPStream(const TCPStream &source); 00327 00328 00329 protected: 00330 timeout_t timeout; 00331 size_t bufsize; 00332 Family family; 00333 char *gbuf, *pbuf; 00334 00335 public: 00340 TCPStream(Family family = IPV4, bool throwflag = true, timeout_t to = 0); 00341 00345 void disconnect(void); 00346 00350 int getSegmentSize(void); 00351 00352 protected: 00359 void allocate(size_t size); 00360 00365 void endStream(void); 00366 00373 int underflow(); 00374 00383 int uflow(); 00384 00392 int overflow(int ch); 00393 00402 void connect(const IPV4Host &host, tpport_t port, unsigned mss = 536); 00403 #ifdef CCXX_IPV6 00404 void connect(const IPV6Host &host, tpport_t port, unsigned mss = 536); 00405 #endif 00406 00414 void connect(const char *name, unsigned mss = 536); 00415 00423 std::iostream *tcp(void) 00424 {return ((std::iostream *)this);}; 00425 00426 public: 00436 TCPStream(TCPSocket &server, bool throwflag = true, timeout_t timeout = 0); 00437 #ifdef CCXX_IPV6 00438 TCPStream(TCPV6Socket &server, bool throwflag = true, timeout_t timeout = 0); 00439 #endif 00440 00446 void connect(TCPSocket &server); 00447 #ifdef CCXX_IPV6 00448 void connect(TCPV6Socket &server); 00449 #endif 00450 00461 TCPStream(const IPV4Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0); 00462 #ifdef CCXX_IPV6 00463 TCPStream(const IPV6Host &host, tpport_t port, unsigned mss = 536, bool throwflag = true, timeout_t timeout = 0); 00464 #endif 00465 00475 TCPStream(const char *name, Family family = IPV4, unsigned mss = 536, bool throwflag = false, timeout_t timer = 0); 00476 00482 inline void setTimeout(timeout_t timer) 00483 {timeout = timer;}; 00484 00485 00490 virtual ~TCPStream(); 00491 00498 int sync(void); 00499 00506 size_t printf(const char *format, ...); 00507 00515 bool isPending(Pending pend, timeout_t timeout = TIMEOUT_INF); 00516 00524 inline ssize_t peek(void *buf, size_t len) 00525 {return ::recv(so, (char *)buf, len, MSG_PEEK);}; 00526 00532 inline size_t getBufferSize(void) const 00533 {return bufsize;}; 00534 }; 00535 00546 class __EXPORT TCPSession : public Thread, public TCPStream 00547 { 00548 private: 00549 TCPSession(const TCPSession &rhs); // not defined 00550 protected: 00563 int waitConnection(timeout_t timeout = TIMEOUT_INF); 00564 00571 void initial(void); 00572 00573 public: 00584 TCPSession(const IPV4Host &host, 00585 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0); 00586 #ifdef CCXX_IPV6 00587 TCPSession(const IPV6Host &host, 00588 tpport_t port, size_t size = 536, int pri = 0, size_t stack = 0); 00589 #endif 00590 00600 TCPSession(TCPSocket &server, int pri = 0, size_t stack = 0); 00601 #ifdef CCXX_IPV6 00602 TCPSession(TCPV6Socket &server, int pri = 0, size_t stack = 0); 00603 #endif 00604 00608 virtual ~TCPSession(); 00609 }; 00610 00611 END_NAMESPACE 00612 00613 #endif