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>
00068
00069 #ifndef MSG_DONTWAIT
00070 #define MSG_DONTWAIT 0
00071 #endif
00072
00077 typedef enum
00078 {
00079 SOCKET_INITIAL,
00080 SOCKET_AVAILABLE,
00081 SOCKET_BOUND,
00082 SOCKET_CONNECTED,
00083 SOCKET_CONNECTING,
00084 SOCKET_STREAM
00085 } sockstate_t;
00086
00087 typedef enum
00088 {
00089 SOCKET_SUCCESS = 0,
00090 SOCKET_CREATE_FAILED,
00091 SOCKET_COPY_FAILED,
00092 SOCKET_INPUT_ERROR,
00093 SOCKET_INPUT_INTERRUPT,
00094 SOCKET_RESOURCE_FAILURE,
00095 SOCKET_OUTPUT_ERROR,
00096 SOCKET_OUTPUT_INTERRUPT,
00097 SOCKET_NOT_CONNECTED,
00098 SOCKET_CONNECT_REFUSED,
00099 SOCKET_CONNECT_REJECTED,
00100 SOCKET_CONNECT_TIMEOUT,
00101 SOCKET_CONNECT_FAILED,
00102 SOCKET_CONNECT_INVALID,
00103 SOCKET_CONNECT_BUSY,
00104 SOCKET_CONNECT_NOROUTE,
00105 SOCKET_BINDING_FAILED,
00106 SOCKET_BROADCAST_DENIED,
00107 SOCKET_ROUTING_DENIED,
00108 SOCKET_KEEPALIVE_DENIED,
00109 SOCKET_SERVICE_DENIED,
00110 SOCKET_SERVICE_UNAVAILABLE,
00111 SOCKET_MULTICAST_DISABLED,
00112 SOCKET_TIMEOUT_ERROR,
00113 SOCKET_NODELAY_ERROR,
00114 SOCKET_EXTENDED_ERROR
00115 } sockerror_t;
00116
00117 typedef enum
00118 {
00119 SOCKET_IPTOS_LOWDELAY,
00120 SOCKET_IPTOS_THROUGHPUT,
00121 SOCKET_IPTOS_RELIABILITY,
00122 SOCKET_IPTOS_MINCOST,
00123 SOCKET_IPTOS_INVALID
00124 } socktos_t;
00125
00126 typedef enum
00127 {
00128 SOCKET_PENDING_INPUT,
00129 SOCKET_PENDING_OUTPUT,
00130 SOCKET_PENDING_ERROR
00131 } sockpend_t;
00132
00136 typedef unsigned short tpport_t;
00137
00138 class __EXPORT InetAddress;
00139 class __EXPORT InetHostAddress;
00140 class __EXPORT InetMaskAddress;
00141 class __EXPORT BroadcastAddress;
00142 class __EXPORT Socket;
00143 class __EXPORT UDPSocket;
00144 class __EXPORT UDPBroadcast;
00145 class __EXPORT UDPTransmit;
00146 class __EXPORT UDPReceive;
00147 class __EXPORT UDPDuplex;
00148 class __EXPORT TCPSocket;
00149 class __EXPORT TCPStream;
00150 class __EXPORT tcpstream;
00151 class __EXPORT TCPSession;
00152
00161 class InetAddrValidator
00162 {
00163 public:
00167 InetAddrValidator() { };
00168
00173 inline virtual void
00174 operator()(const in_addr address) const = 0;
00175 };
00176
00185 class InetMcastAddrValidator: public InetAddrValidator
00186 {
00187 public:
00191 InetMcastAddrValidator(){};
00192
00197 inline void
00198 operator()(const in_addr address) const;
00199 private:
00200 #if __BYTE_ORDER == __BIG_ENDIAN
00201 static const uint32 MCAST_VALID_MASK = 0xF0000000;
00202 static const uint32 MCAST_VALID_VALUE = 0xE0000000;
00203 #else
00204 static const uint32 MCAST_VALID_MASK = 0x000000F0;
00205 static const uint32 MCAST_VALID_VALUE = 0x000000E0;
00206 #endif
00207 };
00208
00223 class InetAddress
00224 {
00225 private:
00226
00227
00228
00229
00230
00231 const InetAddrValidator *validator;
00232
00233 protected:
00234 struct in_addr * ipaddr;
00235 size_t addr_count;
00236 #if defined(WIN32)
00237 static MutexCounter counter;
00238 #else
00239 static Mutex mutex;
00240 #endif
00241
00248 bool setIPAddress(const char *host);
00249
00256 void setAddress(const char *host);
00257
00258 public:
00266 InetAddress(const InetAddrValidator *validator = NULL);
00267
00276 InetAddress(struct in_addr addr, const InetAddrValidator *validator = NULL);
00277
00288 InetAddress(const char *address, const InetAddrValidator *validator = NULL);
00289
00293 InetAddress(const InetAddress &rhs);
00294
00298 virtual ~InetAddress();
00299
00306 const char *getHostname(void) const;
00307
00315 bool isInetAddress(void) const;
00316
00324 struct in_addr getAddress(void) const;
00325
00337 struct in_addr getAddress(size_t i) const;
00338
00344 size_t getAddressCount() const { return addr_count; }
00345
00346 InetAddress &operator=(const char *str);
00347 InetAddress &operator=(struct in_addr addr);
00348 InetAddress &operator=(const InetAddress &rhs);
00349
00354 InetAddress &operator=(unsigned long addr);
00355
00356 inline bool operator!() const
00357 {return !isInetAddress();};
00358
00367 bool operator==(const InetAddress &a) const;
00368
00376 bool operator!=(const InetAddress &a) const;
00377 };
00378
00391 class InetMaskAddress : public InetAddress
00392 {
00393 public:
00400 InetMaskAddress(const char *mask);
00401
00412 friend InetHostAddress operator&(const InetHostAddress &addr,
00413 const InetMaskAddress &mask);
00414
00419 InetAddress &operator=(unsigned long addr)
00420 { return InetAddress::operator =(addr); }
00421 };
00422
00430 class InetHostAddress : public InetAddress
00431 {
00432 public:
00445 InetHostAddress(const char *host = NULL);
00446
00454 InetHostAddress(struct in_addr addr);
00455
00460 InetAddress &operator=(unsigned long addr)
00461 { return InetAddress::operator =(addr); }
00462
00467 InetHostAddress &operator&=(const InetMaskAddress &mask);
00468
00469 friend class InetMaskAddress;
00470 friend InetHostAddress operator&(const InetHostAddress &addr,
00471 const InetMaskAddress &mask);
00472 };
00473
00478 class BroadcastAddress : public InetAddress
00479 {
00480 public:
00488 BroadcastAddress(const char *net = "255.255.255.255");
00489 };
00490
00500 class InetMcastAddress: public InetAddress
00501 {
00502 public:
00507 InetMcastAddress();
00508
00515 InetMcastAddress(const struct in_addr address);
00516
00526 InetMcastAddress(const char *address);
00527
00528 private:
00536 static const InetMcastAddrValidator validator;
00537 };
00538
00556 class Socket
00557 {
00558 private:
00559
00560 mutable sockerror_t errid;
00561 mutable const char *errstr;
00562
00563 void setSocket(void);
00564
00565 protected:
00566 mutable struct
00567 {
00568 bool thrown: 1;
00569 bool broadcast: 1;
00570 bool route: 1;
00571 bool keepalive: 1;
00572 bool loopback: 1;
00573 bool multicast: 1;
00574 bool completion: 1;
00575 bool linger: 1;
00576 unsigned ttl: 8;
00577 } flags;
00578
00584 SOCKET so;
00585 sockstate_t state;
00586
00594 sockerror_t Error(sockerror_t error, char *errstr = NULL) const;
00595
00602 inline void Error(char *estr)
00603 {Error(SOCKET_EXTENDED_ERROR, estr);};
00604
00611 inline void setError(bool enable)
00612 {flags.thrown = !enable;};
00613
00619 void endSocket(void);
00620
00626 sockerror_t connectError(void);
00627
00636 sockerror_t setBroadcast(bool enable);
00637
00648 sockerror_t setMulticast(bool enable);
00649
00657 sockerror_t setLoopback(bool enable);
00658
00665 sockerror_t setTimeToLive(unsigned char ttl);
00666
00673 sockerror_t Join(const InetMcastAddress &ia);
00674
00681 sockerror_t Drop(const InetMcastAddress &ia);
00682
00690 sockerror_t setRouting(bool enable);
00691
00692
00699 sockerror_t setNoDelay(bool enable);
00700
00712 Socket(int domain, int type, int protocol = 0);
00713
00721 Socket(SOCKET fd);
00722
00730 Socket(const Socket &source);
00731
00741 ssize_t Readline(char *buf, size_t len, timeout_t timeout = 0);
00742
00743 public:
00751 virtual ~Socket()
00752 {endSocket();};
00753
00757 Socket &operator=(const Socket &from);
00758
00768 InetHostAddress getSender(tpport_t *port = NULL) const;
00769
00779 InetHostAddress getPeer(tpport_t *port = NULL) const;
00780
00788 InetHostAddress getLocal(tpport_t *port = NULL) const;
00789
00800 void setCompletion(bool immediate);
00801
00807 sockerror_t setLinger(bool linger);
00808
00816 sockerror_t setKeepAlive(bool enable);
00817
00826 sockerror_t setTypeOfService(socktos_t service);
00827
00836 bool isConnected(void) const;
00837
00845 bool isActive(void) const;
00846
00851 bool operator!() const;
00852
00859 inline bool isBroadcast(void) const
00860 {return flags.broadcast;};
00861
00867 inline bool isRouted(void) const
00868 {return flags.route;};
00869
00876 inline sockerror_t getErrorNumber(void) const {return errid;}
00877
00884 inline const char *getErrorString(void) const {return errstr;}
00885
00895 virtual bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
00896 };
00897
00930 class UDPSocket : public Socket
00931 {
00932 private:
00933 inline sockerror_t setKeepAlive(bool enable)
00934 {return Socket::setKeepAlive(enable);};
00935
00936 protected:
00937 struct sockaddr_in peer;
00938
00939 public:
00943 UDPSocket(void);
00944
00954 UDPSocket(const InetAddress &bind, tpport_t port);
00955
00959 ~UDPSocket()
00960 {endSocket();};
00961
00969 void setPeer(const InetHostAddress &host, tpport_t port);
00970
00978 inline int Send(void *buf, size_t len)
00979 {return ::sendto(so, (const char *)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00980
00988 inline int Recv(void *buf, size_t len)
00989 {return ::recv(so, (char *)buf, len, 0);};
00990
00999 InetHostAddress getPeer(tpport_t *port = NULL) const;
01000
01008 inline int Peek(void *buf, size_t len)
01009 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01010 };
01011
01012
01021 class UDPBroadcast : public UDPSocket
01022 {
01023 private:
01024 void setPeer(const InetHostAddress &ia, tpport_t port) {};
01025
01026 sockerror_t setBroadcast(bool enable)
01027 {return Socket::setBroadcast(enable);};
01028
01029 public:
01036 UDPBroadcast(const InetAddress &ia, tpport_t port);
01037
01044 void setPeer(const BroadcastAddress &subnet, tpport_t port);
01045 };
01046
01055 class UDPTransmit : private UDPSocket
01056 {
01057 protected:
01061 UDPTransmit();
01062
01075 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
01076
01085 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01086
01095 sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port);
01096
01101 sockerror_t Disconnect(void);
01102
01110 inline int Send(void *buf, int len)
01111 {return ::send(so, (char *)buf, len, 0);}
01112
01116 inline void endTransmitter(void)
01117 {Socket::endSocket();}
01118
01119
01120
01121
01122
01123
01124 inline SOCKET getTransmitter(void)
01125 {return so;};
01126
01127 public:
01137 inline int Transmit(const char *buffer, size_t len)
01138 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01139
01146 inline bool isOutputReady(unsigned long timeout = 0l)
01147 {return Socket::isPending(SOCKET_PENDING_OUTPUT, timeout);};
01148
01149
01150 inline sockerror_t setRouting(bool enable)
01151 {return Socket::setRouting(enable);};
01152
01153 inline sockerror_t setTypeOfService(socktos_t tos)
01154 {return Socket::setTypeOfService(tos);};
01155
01156 inline sockerror_t setBroadcast(bool enable)
01157 {return Socket::setBroadcast(enable);};
01158 };
01159
01168 class UDPReceive : private UDPSocket
01169 {
01170 protected:
01182 UDPReceive(const InetAddress &bind, tpport_t port);
01183
01192 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01193
01198 sockerror_t Disconnect(void);
01199
01206 bool isPendingReceive(timeout_t timeout)
01207 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01208
01212 inline void endReceiver(void)
01213 {Socket::endSocket();}
01214
01215 inline SOCKET getReceiver(void)
01216 {return so;};
01217
01218 inline sockerror_t setRouting(bool enable)
01219 {return Socket::setRouting(enable);};
01220
01221 public:
01229 inline int Receive(void *buf, size_t len)
01230 {return ::recv(so, (char *)buf, len, 0);};
01231
01238 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01239 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01240 };
01241
01252 class UDPDuplex : public UDPTransmit, public UDPReceive
01253 {
01254 public:
01263 UDPDuplex(const InetAddress &bind, tpport_t port);
01264
01274 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01275
01282 sockerror_t Disconnect(void);
01283 };
01284
01285
01310 class TCPSocket : private Socket
01311 {
01312 protected:
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01336 virtual bool OnAccept(const InetHostAddress &ia, tpport_t port)
01337 {return true;};
01338
01339 friend class TCPStream;
01340 friend class SocketPort;
01341 friend class tcpstream;
01342
01343 public:
01355 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01356
01365 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01366 {return Socket::getSender(port);};
01367
01371 void Reject(void);
01372
01376 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01377 {return Socket::getLocal(port);};
01378
01382 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01383 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);}
01384
01388 ~TCPSocket()
01389 {endSocket();};
01390 };
01391
01392
01393
01394
01395
01396
01397
01398
01399 #ifdef _MSC_VER
01400 #pragma warning(disable:4275) // disable C4275 warning
01401 #endif
01402
01416 #if defined(STLPORT) || defined(__KCC)
01417 #define std::iostream std::iostream_withassign
01418 #endif
01419 #ifdef __KCC
01420 using std::iostream;
01421 #endif
01422 class TCPStream : public Socket, public std::streambuf, public std::iostream
01423 {
01424 private:
01425 inline sockerror_t setBroadcast(bool enable)
01426 {return Socket::setBroadcast(enable);};
01427
01428 inline InetHostAddress getSender(tpport_t *port) const
01429 {return InetHostAddress();};
01430
01431 int doallocate();
01432
01433 friend TCPStream& crlf(TCPStream&);
01434 friend TCPStream& lfcr(TCPStream&);
01435
01436 protected:
01437 timeout_t timeout;
01438 int bufsize;
01439 char *gbuf, *pbuf;
01440
01445 TCPStream(bool throwflag = true);
01446
01453 void Allocate(int size);
01454
01459 void endStream(void);
01460
01467 virtual int underflow(void);
01468
01477 int uflow(void);
01478
01486 int overflow(int ch);
01487
01496 void Connect(const InetHostAddress &host, tpport_t port, int size);
01497
01505 std::iostream *tcp(void)
01506 {return ((std::iostream *)this);};
01507
01508 public:
01518 TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01519
01530 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t to = 0);
01531
01537 inline void setTimeout(timeout_t to)
01538 {timeout = to;};
01539
01546 TCPStream(const TCPStream &source);
01547
01552 virtual ~TCPStream()
01553 {endStream();};
01554
01561 int sync(void);
01562
01570 bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
01571
01577 int getBufferSize(void) const
01578 {return bufsize;};
01579 };
01580
01589 class tcpstream : public TCPStream
01590 {
01591 public:
01595 tcpstream();
01596
01604 tcpstream(const char *addr, int buffer = 512);
01605
01613 tcpstream(TCPSocket &tcp, int buffer = 512);
01614
01622 void open(const char *addr, int buffer = 512);
01623
01630 void open(TCPSocket &tcp, int buffer = 512);
01631
01635 void close(void);
01636
01640 bool operator!() const;
01641 };
01642
01653 class TCPSession : public TCPStream, public Thread
01654 {
01655 protected:
01668 int WaitConnection(timeout_t timeout = TIMEOUT_INF);
01669
01676 void Initial(void);
01677
01683 void Final(void)
01684 {delete this;};
01685 public:
01697 TCPSession(Semaphore *start, const InetHostAddress &host,
01698 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01699
01711 TCPSession(Semaphore *start, TCPSocket &server, int size = 512,
01712 int pri = 0, int stack = 0);
01713 };
01714
01715 extern __EXPORT std::ostream &operator<<(std::ostream &os, const InetAddress &ia);
01716
01717 inline struct in_addr getaddress(const InetAddress &ia)
01718 {return ia.getAddress();}
01719
01720 #if defined(WIN32)
01721
01735 class init_WSA
01736 {
01737 public:
01738 init_WSA();
01739 private:
01740 WSADATA wsaData;
01741 };
01742
01743 #else // !WIN32
01744
01745 class SocketService;
01746
01766 class SocketPort : public Socket, public TimerPort
01767 {
01768 private:
01769 SocketPort *next, *prev;
01770 SocketService *service;
01771 struct timeval porttimer;
01772 #ifdef __CCXX_USE_POLL
01773 struct pollfd * ufd;
01774 #endif
01775 bool detect_pending;
01776 bool detect_output;
01777 bool detect_disconnect;
01778
01779 friend class SocketService;
01780
01781 protected:
01790 SocketPort(SocketService *svc, TCPSocket &tcp);
01791
01800 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01801
01807 void Attach( SocketService* svc );
01808
01809
01814 virtual ~SocketPort();
01815
01820 void setDetectPending( bool );
01821
01825 bool getDetectPending( void ) const
01826 { return detect_pending; }
01827
01832 void setDetectOutput( bool );
01833
01837 bool getDetectOutput( void ) const
01838 { return detect_output; }
01839
01844 virtual void Expired(void)
01845 {return;};
01846
01851 virtual void Pending(void)
01852 {return;};
01853
01858 virtual void Output(void)
01859 {return;};
01860
01865 virtual void Disconnect(void)
01866 {return;};
01867
01878 sockerror_t Connect(const InetAddress &ia, tpport_t port);
01879
01889 inline int Send(void *buf, int len)
01890 {return ::send(so, (char *)buf, len, 0);};
01891
01900 inline int Recv(void *buf, size_t len)
01901 {return ::recv(so, (char *)buf, len, 0);};
01902
01911 inline int Peek(void *buf, size_t len)
01912 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01913
01914 public:
01922 void setTimer(timeout_t timeout = 0);
01923
01931 void incTimer(timeout_t timeout);
01932 };
01933
01946 class SocketService : public Thread, private Mutex
01947 {
01948 private:
01949 fd_set connect;
01950 int iosync[2];
01951 int hiwater;
01952 int count;
01953 SocketPort *first, *last;
01954
01960 void Attach(SocketPort *port);
01966 void Detach(SocketPort *port);
01967
01971 void Run(void);
01972
01973 friend class SocketPort;
01974
01975 protected:
01981 virtual void OnUpdate(unsigned char buf)
01982 {return;};
01983
01989 virtual void OnEvent(void)
01990 {return;};
01991
01999 virtual void OnCallback(SocketPort *port)
02000 {return;};
02001
02002 public:
02013 void Update(unsigned char flag = 0xff);
02014
02021 SocketService(int pri = 0);
02022
02027 ~SocketService();
02028
02035 inline int getCount(void) const
02036 {return count;};
02037 };
02038
02039 #ifdef __CCXX_NAMESPACE_H__
02040 #undef __CCXX_NAMESPACE_H__
02041 #include <cc++/namespace.h>
02042 #endif
02043
02044 #endif // !WIN32
02045
02046 #endif
02047