00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef __CCXX_SOCKET_H__
00042 #define __CCXX_SOCKET_H__
00043
00044 #include "config.h"
00045
00046 #if defined(WIN32)
00047 # ifndef __CCXX_THREAD_H__
00048 # include <thread.h>
00049 # endif
00050 # include <winsock.h>
00051 # define TIMEOUT_INF ~((timeout_t) 0)
00052 typedef int socklen_t;
00053 #else
00054 # ifndef __CCXX_THREAD_H__
00055 # include <cc++/thread.h>
00056 # elif defined(__CCXX_NAMESPACE_H__)
00057 # include <cc++/macros.h>
00058 # endif
00059 # define INVALID_SOCKET -1
00060 # ifdef __EXPORT
00061 # undef __EXPORT
00062 # endif
00063 # define __EXPORT
00064 typedef int SOCKET;
00065 #endif
00066
00067 #include <iostream.h>
00068
00069 #ifndef MSG_DONTWAIT
00070 #define MSG_DONTWAIT 0
00071 #endif
00072
00077 typedef enum
00078 {
00079 SOCKET_COMPLETION_IMMEDIATE,
00080 SOCKET_COMPLETION_DELAYED
00081 } sockcomplete_t;
00082
00083 typedef enum
00084 {
00085 SOCKET_INITIAL,
00086 SOCKET_AVAILABLE,
00087 SOCKET_BOUND,
00088 SOCKET_CONNECTED,
00089 SOCKET_CONNECTING,
00090 SOCKET_STREAM
00091 } sockstate_t;
00092
00093 typedef enum
00094 {
00095 SOCKET_SUCCESS = 0,
00096 SOCKET_CREATE_FAILED,
00097 SOCKET_COPY_FAILED,
00098 SOCKET_INPUT_ERROR,
00099 SOCKET_INPUT_INTERRUPT,
00100 SOCKET_RESOURCE_FAILURE,
00101 SOCKET_OUTPUT_ERROR,
00102 SOCKET_OUTPUT_INTERRUPT,
00103 SOCKET_NOT_CONNECTED,
00104 SOCKET_CONNECT_REFUSED,
00105 SOCKET_CONNECT_REJECTED,
00106 SOCKET_CONNECT_TIMEOUT,
00107 SOCKET_CONNECT_FAILED,
00108 SOCKET_CONNECT_INVALID,
00109 SOCKET_CONNECT_BUSY,
00110 SOCKET_CONNECT_NOROUTE,
00111 SOCKET_BINDING_FAILED,
00112 SOCKET_BROADCAST_DENIED,
00113 SOCKET_ROUTING_DENIED,
00114 SOCKET_KEEPALIVE_DENIED,
00115 SOCKET_SERVICE_DENIED,
00116 SOCKET_SERVICE_UNAVAILABLE,
00117 SOCKET_MULTICAST_DISABLED,
00118 SOCKET_EXTENDED_ERROR
00119 } sockerror_t;
00120
00121 typedef enum
00122 {
00123 SOCKET_IPTOS_LOWDELAY,
00124 SOCKET_IPTOS_THROUGHPUT,
00125 SOCKET_IPTOS_RELIABILITY,
00126 SOCKET_IPTOS_MINCOST,
00127 SOCKET_IPTOS_INVALID
00128 } socktos_t;
00129
00130 typedef enum
00131 {
00132 SOCKET_PENDING_INPUT,
00133 SOCKET_PENDING_OUTPUT,
00134 SOCKET_PENDING_ERROR
00135 } sockpend_t;
00136
00140 typedef unsigned short tpport_t;
00141
00142 class __EXPORT InetAddress;
00143 class __EXPORT InetHostAddress;
00144 class __EXPORT InetMaskAddress;
00145 class __EXPORT BroadcastAddress;
00146 class __EXPORT Socket;
00147 class __EXPORT UDPSocket;
00148 class __EXPORT UDPBroadcast;
00149 class __EXPORT UDPTransmit;
00150 class __EXPORT UDPReceive;
00151 class __EXPORT UDPDuplex;
00152 class __EXPORT TCPSocket;
00153 class __EXPORT TCPStream;
00154 class __EXPORT tcpstream;
00155 class __EXPORT TCPSession;
00156
00171 class InetAddress
00172 {
00173 protected:
00174 struct in_addr * ipaddr;
00175 size_t addr_count;
00176 #if defined(WIN32)
00177 static MutexCounter counter;
00178 #else
00179 static Mutex mutex;
00180 #endif
00181
00188 bool setIPAddress(const char *host);
00189
00196 void setAddress(const char *host);
00197
00198 public:
00203 InetAddress();
00204
00212 InetAddress(struct in_addr addr);
00213
00220 InetAddress(const char *address);
00221
00225 InetAddress(const InetAddress &rhs);
00226
00230 virtual ~InetAddress();
00231
00238 const char *getHostname(void) const;
00239
00247 bool isInetAddress(void) const;
00248
00256 struct in_addr getAddress(void) const;
00257
00269 struct in_addr getAddress(size_t i) const;
00270
00276 size_t getAddressCount() const { return addr_count; }
00277
00278 InetAddress &operator=(const char *str);
00279 InetAddress &operator=(struct in_addr addr);
00280 InetAddress &operator=(const InetAddress &rhs);
00281
00285 InetAddress &operator=(unsigned long addr);
00286
00287 inline bool operator!() const
00288 {return !isInetAddress();};
00289
00298 bool operator==(const InetAddress &a) const;
00299
00307 bool operator!=(const InetAddress &a) const;
00308 };
00309
00322 class InetMaskAddress : public InetAddress
00323 {
00324 public:
00331 InetMaskAddress(const char *mask);
00332
00343 friend InetHostAddress operator&(const InetHostAddress &addr,
00344 const InetMaskAddress &mask);
00345
00349 InetAddress &operator=(unsigned long addr)
00350 { return InetAddress::operator =(addr); }
00351 };
00352
00360 class InetHostAddress : public InetAddress
00361 {
00362 public:
00375 InetHostAddress(const char *host = NULL);
00376
00384 InetHostAddress(struct in_addr addr);
00385
00389 InetAddress &operator=(unsigned long addr)
00390 { return InetAddress::operator =(addr); }
00391
00396 InetHostAddress &operator&=(const InetMaskAddress &mask);
00397
00398 friend class InetMaskAddress;
00399 friend InetHostAddress operator&(const InetHostAddress &addr,
00400 const InetMaskAddress &mask);
00401 };
00402
00407 class BroadcastAddress : public InetAddress
00408 {
00409 public:
00417 BroadcastAddress(const char *net = "255.255.255.255");
00418 };
00419
00437 class Socket
00438 {
00439 private:
00440
00441 mutable sockerror_t errid;
00442 mutable const char *errstr;
00443
00444 mutable struct
00445 {
00446 bool thrown: 1;
00447 bool broadcast: 1;
00448 bool route: 1;
00449 bool keepalive: 1;
00450 bool loopback: 1;
00451 bool multicast: 1;
00452 unsigned ttl: 8;
00453 } flags;
00454
00455 void setSocket(void);
00456
00457 protected:
00463 SOCKET so;
00464 sockstate_t state;
00465
00473 sockerror_t Error(sockerror_t error, char *errstr = NULL) const;
00474
00481 inline void Error(char *estr)
00482 {Error(SOCKET_EXTENDED_ERROR, estr);};
00483
00490 inline void setError(bool enable)
00491 {flags.thrown = !enable;};
00492
00498 void endSocket(void);
00499
00505 sockerror_t connectError(void);
00506
00515 sockerror_t setBroadcast(bool enable);
00516
00527 sockerror_t setMulticast(bool enable);
00528
00536 sockerror_t setLoopback(bool enable);
00537
00544 sockerror_t setTimeToLive(unsigned char ttl);
00545
00552 sockerror_t Join(InetAddress &ia);
00553
00560 sockerror_t Drop(InetAddress &ia);
00561
00569 sockerror_t setRouting(bool enable);
00570
00582 Socket(int domain, int type, int protocol = 0);
00583
00591 Socket(SOCKET fd);
00592
00600 Socket(const Socket &source);
00601
00610 ssize_t Readline(char *buf, size_t len);
00611
00612 public:
00620 virtual ~Socket()
00621 {endSocket();};
00622
00626 Socket &operator=(const Socket &from);
00627
00637 InetHostAddress getSender(tpport_t *port = NULL) const;
00638
00648 InetHostAddress getPeer(tpport_t *port = NULL) const;
00649
00657 InetHostAddress getLocal(tpport_t *port = NULL) const;
00658
00669 void setCompletion(sockcomplete_t completion);
00670
00678 sockerror_t setKeepAlive(bool enable);
00679
00688 sockerror_t setTypeOfService(socktos_t service);
00689
00698 bool isConnected(void) const;
00699
00707 bool isActive(void) const;
00708
00713 bool operator!() const;
00714
00721 inline bool isBroadcast(void) const
00722 {return flags.broadcast;};
00723
00729 inline bool isRouted(void) const
00730 {return flags.route;};
00731
00738 inline sockerror_t getErrorNumber(void) const {return errid;}
00739
00746 inline const char *getErrorString(void) const {return errstr;}
00747
00757 virtual bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
00758 };
00759
00792 class UDPSocket : public Socket
00793 {
00794 private:
00795 inline sockerror_t setKeepAlive(bool enable)
00796 {return Socket::setKeepAlive(enable);};
00797
00798 protected:
00799 struct sockaddr_in peer;
00800
00801 public:
00805 UDPSocket(void);
00806
00816 UDPSocket(const InetAddress &bind, tpport_t port);
00817
00821 ~UDPSocket()
00822 {endSocket();};
00823
00831 void setPeer(const InetHostAddress &host, tpport_t port);
00832
00840 inline int Send(void *buf, size_t len)
00841 {return ::sendto(so, (const char *)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00842
00850 inline int Recv(void *buf, size_t len)
00851 {return ::recv(so, (char *)buf, len, 0);};
00852
00861 InetHostAddress getPeer(tpport_t *port = NULL) const;
00862
00870 inline int Peek(void *buf, size_t len)
00871 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
00872 };
00873
00874
00883 class UDPBroadcast : public UDPSocket
00884 {
00885 private:
00886 void setPeer(const InetHostAddress &ia, tpport_t port) {};
00887
00888 sockerror_t setBroadcast(bool enable)
00889 {return Socket::setBroadcast(enable);};
00890
00891 public:
00898 UDPBroadcast(const InetAddress &ia, tpport_t port);
00899
00906 void setPeer(const BroadcastAddress &subnet, tpport_t port);
00907 };
00908
00917 class UDPTransmit : private UDPSocket
00918 {
00919 protected:
00923 UDPTransmit();
00924
00937 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
00938
00947 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
00948
00957 sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port);
00958
00963 sockerror_t Disconnect(void);
00964
00972 inline int Send(void *buf, int len)
00973 {return ::send(so, (char *)buf, len, 0);}
00974
00978 inline void endTransmitter(void)
00979 {Socket::endSocket();}
00980
00981 00982 00983 00984 00985
00986 inline SOCKET getTransmitter(void)
00987 {return so;};
00988
00989 public:
00999 inline int Transmit(const char *buffer, size_t len)
01000 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01001
01008 inline bool isOutputReady(unsigned long timeout = 0l)
01009 {return Socket::isPending(SOCKET_PENDING_OUTPUT, timeout);};
01010
01011
01012 inline sockerror_t setRouting(bool enable)
01013 {return Socket::setRouting(enable);};
01014
01015 inline sockerror_t setTypeOfService(socktos_t tos)
01016 {return Socket::setTypeOfService(tos);};
01017
01018 inline sockerror_t setBroadcast(bool enable)
01019 {return Socket::setBroadcast(enable);};
01020 };
01021
01030 class UDPReceive : private UDPSocket
01031 {
01032 protected:
01044 UDPReceive(const InetAddress &bind, tpport_t port);
01045
01054 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01055
01060 sockerror_t Disconnect(void);
01061
01068 bool isPendingReceive(timeout_t timeout)
01069 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01070
01074 inline void endReceiver(void)
01075 {Socket::endSocket();}
01076
01077 inline SOCKET getReceiver(void)
01078 {return so;};
01079
01080 inline sockerror_t setRouting(bool enable)
01081 {return Socket::setRouting(enable);};
01082
01083 public:
01091 inline int Receive(void *buf, size_t len)
01092 {return ::recv(so, (char *)buf, len, 0);};
01093
01100 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01101 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01102 };
01103
01114 class UDPDuplex : public UDPTransmit, public UDPReceive
01115 {
01116 public:
01125 UDPDuplex(const InetAddress &bind, tpport_t port);
01126
01136 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01137
01144 sockerror_t Disconnect(void);
01145 };
01146
01147
01172 class TCPSocket : private Socket
01173 {
01174 protected:
01182 virtual bool OnAccept(const InetHostAddress &ia, short port) {
01183 return false;
01184 }
01185
01197 virtual bool OnAccept(const InetHostAddress &ia, tpport_t port)
01198 {return true;};
01199
01200 friend class TCPStream;
01201 friend class SocketPort;
01202 friend class tcpstream;
01203
01204 public:
01216 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01217
01226 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01227 {return Socket::getSender(port);};
01228
01232 void Reject(void);
01233
01237 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01238 {return Socket::getLocal(port);};
01239
01243 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01244 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);}
01245
01249 ~TCPSocket()
01250 {endSocket();};
01251 };
01252
01253 01254 01255 01256 01257 01258
01259
01260 #ifndef __KCC
01261 #pragma warning(disable:4275) // disable C4275 warning
01262 #endif
01263
01277 #if defined(STLPORT) || defined(__KCC)
01278 #define iostream iostream_withassign
01279 #endif
01280 #ifdef __KCC
01281 using std::iostream;
01282 #endif
01283 class TCPStream : public Socket, public streambuf, public iostream
01284 {
01285 private:
01286 inline sockerror_t setBroadcast(bool enable)
01287 {return Socket::setBroadcast(enable);};
01288
01289 inline InetHostAddress getSender(tpport_t *port) const
01290 {return InetHostAddress();};
01291
01292 int doallocate();
01293
01294 friend TCPStream& crlf(TCPStream&);
01295 friend TCPStream& lfcr(TCPStream&);
01296
01297 protected:
01298 int bufsize;
01299 char *gbuf, *pbuf;
01300
01305 TCPStream();
01306
01313 void Allocate(int size);
01314
01319 void endStream(void);
01320
01327 virtual int underflow(void);
01328
01337 int uflow(void);
01338
01346 int overflow(int ch);
01347
01356 void Connect(const InetHostAddress &host, tpport_t port, int size);
01357
01365 iostream *tcp(void)
01366 {return ((iostream *)this);};
01367
01368 public:
01376 TCPStream(TCPSocket &server, int size = 512);
01377
01386 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512);
01387
01394 TCPStream(const TCPStream &source);
01395
01400 ~TCPStream()
01401 {endStream();};
01402
01409 int sync(void);
01410
01418 bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
01419
01425 int getBufferSize(void) const
01426 {return bufsize;};
01427 };
01428
01437 class tcpstream : public TCPStream
01438 {
01439 public:
01443 tcpstream();
01444
01452 tcpstream(const char *addr, int buffer = 512);
01453
01461 tcpstream(TCPSocket &tcp, int buffer = 512);
01462
01470 void open(const char *addr, int buffer = 512);
01471
01478 void open(TCPSocket &tcp, int buffer = 512);
01479
01483 void close(void);
01484
01488 bool operator!() const;
01489 };
01490
01501 class TCPSession : public TCPStream, public Thread
01502 {
01503 protected:
01516 int WaitConnection(timeout_t timeout = TIMEOUT_INF);
01517
01524 void Initial(void);
01525
01531 void Final(void)
01532 {delete this;};
01533 public:
01545 TCPSession(Semaphore *start, const InetHostAddress &host,
01546 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01547
01559 TCPSession(Semaphore *start, TCPSocket &server, int size = 512,
01560 int pri = 0, int stack = 0);
01561 };
01562
01563 extern __EXPORT ::ostream &operator<<(::ostream &os, const InetAddress &ia);
01564
01565 inline struct in_addr getaddress(const InetAddress &ia)
01566 {return ia.getAddress();}
01567
01568 #if defined(WIN32)
01569
01583 class init_WSA
01584 {
01585 public:
01586 init_WSA();
01587 private:
01588 WSADATA wsaData;
01589 };
01590
01591 #else // !WIN32
01592
01593 class SocketService;
01594
01614 class SocketPort : public Socket, public TimerPort
01615 {
01616 private:
01617 SocketPort *next, *prev;
01618 SocketService *service;
01619 struct timeval porttimer;
01620 #ifdef __CCXX_USE_POLL
01621 struct pollfd * ufd;
01622 #endif
01623 bool detect_pending;
01624 bool detect_output;
01625 bool detect_disconnect;
01626
01627 friend class SocketService;
01628
01629 protected:
01638 SocketPort(SocketService *svc, TCPSocket &tcp);
01639
01648 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01649
01655 void Attach( SocketService* svc );
01656
01657
01662 virtual ~SocketPort();
01663
01668 void setDetectPending( bool );
01669
01673 bool getDetectPending( void ) const
01674 { return detect_pending; }
01675
01680 void setDetectOutput( bool );
01681
01685 bool getDetectOutput( void ) const
01686 { return detect_output; }
01687
01692 virtual void Expired(void)
01693 {return;};
01694
01699 virtual void Pending(void)
01700 {return;};
01701
01706 virtual void Output(void)
01707 {return;};
01708
01713 virtual void Disconnect(void)
01714 {return;};
01715
01726 sockerror_t Connect(const InetAddress &ia, tpport_t port);
01727
01737 inline int Send(void *buf, int len)
01738 {return ::send(so, (char *)buf, len, 0);};
01739
01748 inline int Recv(void *buf, size_t len)
01749 {return ::recv(so, (char *)buf, len, 0);};
01750
01759 inline int Peek(void *buf, size_t len)
01760 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01761
01762 public:
01770 void setTimer(timeout_t timeout = 0);
01771
01779 void incTimer(timeout_t timeout);
01780 };
01781
01794 class SocketService : public Thread, private Mutex
01795 {
01796 private:
01797 fd_set connect;
01798 int iosync[2];
01799 int hiwater;
01800 int count;
01801 SocketPort *first, *last;
01802
01808 void Attach(SocketPort *port);
01814 void Detach(SocketPort *port);
01815
01819 void Run(void);
01820
01821 friend class SocketPort;
01822
01823 protected:
01829 virtual void OnUpdate(unsigned char buf)
01830 {return;};
01831
01837 virtual void OnEvent(void)
01838 {return;};
01839
01847 virtual void OnCallback(SocketPort *port)
01848 {return;};
01849
01850 public:
01861 void Update(unsigned char flag = 0xff);
01862
01869 SocketService(int pri = 0);
01870
01875 ~SocketService();
01876
01883 inline int getCount(void) const
01884 {return count;};
01885 };
01886
01887 #ifdef __CCXX_NAMESPACE_H__
01888 #undef __CCXX_NAMESPACE_H__
01889 #include <cc++/namespace.h>
01890 #endif
01891
01892 #endif // !WIN32
01893
01894 #endif
01895