ucommon
commoncpp/tcp.h
Go to the documentation of this file.
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