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 enum
00202 {
00203 MCAST_VALID_MASK = 0xF0000000,
00204 MCAST_VALID_VALUE = 0xE0000000
00205 };
00206 #else
00207 enum
00208 {
00209 MCAST_VALID_MASK = 0x000000F0,
00210 MCAST_VALID_VALUE = 0x000000E0
00211 };
00212 #endif
00213 };
00214
00229 class InetAddress
00230 {
00231 private:
00232
00233
00234
00235
00236
00237 const InetAddrValidator *validator;
00238
00239 protected:
00240 struct in_addr * ipaddr;
00241 size_t addr_count;
00242 #if defined(WIN32)
00243 static MutexCounter counter;
00244 #else
00245 static Mutex mutex;
00246 #endif
00247
00254 bool setIPAddress(const char *host);
00255
00262 void setAddress(const char *host);
00263
00264 public:
00272 InetAddress(const InetAddrValidator *validator = NULL);
00273
00282 InetAddress(struct in_addr addr, const InetAddrValidator *validator = NULL);
00283
00294 InetAddress(const char *address, const InetAddrValidator *validator = NULL);
00295
00299 InetAddress(const InetAddress &rhs);
00300
00304 virtual ~InetAddress();
00305
00312 const char *getHostname(void) const;
00313
00321 bool isInetAddress(void) const;
00322
00330 struct in_addr getAddress(void) const;
00331
00343 struct in_addr getAddress(size_t i) const;
00344
00350 size_t getAddressCount() const { return addr_count; }
00351
00352 InetAddress &operator=(const char *str);
00353 InetAddress &operator=(struct in_addr addr);
00354 InetAddress &operator=(const InetAddress &rhs);
00355
00360 InetAddress &operator=(unsigned long addr);
00361
00362 inline bool operator!() const
00363 {return !isInetAddress();};
00364
00373 bool operator==(const InetAddress &a) const;
00374
00382 bool operator!=(const InetAddress &a) const;
00383 };
00384
00397 class InetMaskAddress : public InetAddress
00398 {
00399 public:
00406 InetMaskAddress(const char *mask);
00407
00418 friend InetHostAddress operator&(const InetHostAddress &addr,
00419 const InetMaskAddress &mask);
00420
00425 InetAddress &operator=(unsigned long addr)
00426 { return InetAddress::operator =(addr); }
00427 };
00428
00436 class InetHostAddress : public InetAddress
00437 {
00438 public:
00451 InetHostAddress(const char *host = NULL);
00452
00460 InetHostAddress(struct in_addr addr);
00461
00466 InetAddress &operator=(unsigned long addr)
00467 { return InetAddress::operator =(addr); }
00468
00473 InetHostAddress &operator&=(const InetMaskAddress &mask);
00474
00475 friend class InetMaskAddress;
00476 friend InetHostAddress operator&(const InetHostAddress &addr,
00477 const InetMaskAddress &mask);
00478 };
00479
00484 class BroadcastAddress : public InetAddress
00485 {
00486 public:
00494 BroadcastAddress(const char *net = "255.255.255.255");
00495 };
00496
00506 class InetMcastAddress: public InetAddress
00507 {
00508 public:
00513 InetMcastAddress();
00514
00521 InetMcastAddress(const struct in_addr address);
00522
00532 InetMcastAddress(const char *address);
00533
00534 private:
00542 static const InetMcastAddrValidator validator;
00543 };
00544
00562 class Socket
00563 {
00564 private:
00565
00566 mutable sockerror_t errid;
00567 mutable const char *errstr;
00568
00569 void setSocket(void);
00570
00571 protected:
00572 mutable struct
00573 {
00574 bool thrown: 1;
00575 bool broadcast: 1;
00576 bool route: 1;
00577 bool keepalive: 1;
00578 bool loopback: 1;
00579 bool multicast: 1;
00580 bool completion: 1;
00581 bool linger: 1;
00582 unsigned ttl: 8;
00583 } flags;
00584
00590 SOCKET so;
00591 sockstate_t state;
00592
00600 sockerror_t Error(sockerror_t error, char *errstr = NULL) const;
00601
00608 inline void Error(char *estr)
00609 {Error(SOCKET_EXTENDED_ERROR, estr);};
00610
00617 inline void setError(bool enable)
00618 {flags.thrown = !enable;};
00619
00625 void endSocket(void);
00626
00632 sockerror_t connectError(void);
00633
00642 sockerror_t setBroadcast(bool enable);
00643
00654 sockerror_t setMulticast(bool enable);
00655
00663 sockerror_t setLoopback(bool enable);
00664
00671 sockerror_t setTimeToLive(unsigned char ttl);
00672
00679 sockerror_t Join(const InetMcastAddress &ia);
00680
00687 sockerror_t Drop(const InetMcastAddress &ia);
00688
00696 sockerror_t setRouting(bool enable);
00697
00698
00705 sockerror_t setNoDelay(bool enable);
00706
00718 Socket(int domain, int type, int protocol = 0);
00719
00727 Socket(SOCKET fd);
00728
00736 Socket(const Socket &source);
00737
00747 ssize_t Readline(char *buf, size_t len, timeout_t timeout = 0);
00748
00749 public:
00757 virtual ~Socket()
00758 {endSocket();};
00759
00763 Socket &operator=(const Socket &from);
00764
00774 InetHostAddress getSender(tpport_t *port = NULL) const;
00775
00785 InetHostAddress getPeer(tpport_t *port = NULL) const;
00786
00794 InetHostAddress getLocal(tpport_t *port = NULL) const;
00795
00806 void setCompletion(bool immediate);
00807
00813 sockerror_t setLinger(bool linger);
00814
00822 sockerror_t setKeepAlive(bool enable);
00823
00832 sockerror_t setTypeOfService(socktos_t service);
00833
00842 bool isConnected(void) const;
00843
00851 bool isActive(void) const;
00852
00857 bool operator!() const;
00858
00865 inline bool isBroadcast(void) const
00866 {return flags.broadcast;};
00867
00873 inline bool isRouted(void) const
00874 {return flags.route;};
00875
00882 inline sockerror_t getErrorNumber(void) const {return errid;}
00883
00890 inline const char *getErrorString(void) const {return errstr;}
00891
00901 virtual bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
00902 };
00903
00936 class UDPSocket : public Socket
00937 {
00938 private:
00939 inline sockerror_t setKeepAlive(bool enable)
00940 {return Socket::setKeepAlive(enable);};
00941
00942 protected:
00943 struct sockaddr_in peer;
00944
00945 public:
00949 UDPSocket(void);
00950
00960 UDPSocket(const InetAddress &bind, tpport_t port);
00961
00965 ~UDPSocket()
00966 {endSocket();};
00967
00975 void setPeer(const InetHostAddress &host, tpport_t port);
00976
00984 inline int Send(void *buf, size_t len)
00985 {return ::sendto(so, (const char *)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00986
00994 inline int Recv(void *buf, size_t len)
00995 {return ::recv(so, (char *)buf, len, 0);};
00996
01005 InetHostAddress getPeer(tpport_t *port = NULL) const;
01006
01014 inline int Peek(void *buf, size_t len)
01015 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01016 };
01017
01018
01027 class UDPBroadcast : public UDPSocket
01028 {
01029 private:
01030 void setPeer(const InetHostAddress &ia, tpport_t port) {};
01031
01032 sockerror_t setBroadcast(bool enable)
01033 {return Socket::setBroadcast(enable);};
01034
01035 public:
01042 UDPBroadcast(const InetAddress &ia, tpport_t port);
01043
01050 void setPeer(const BroadcastAddress &subnet, tpport_t port);
01051 };
01052
01061 class UDPTransmit : private UDPSocket
01062 {
01063 protected:
01067 UDPTransmit();
01068
01081 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
01082
01091 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01092
01101 sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port);
01102
01107 sockerror_t Disconnect(void);
01108
01116 inline int Send(void *buf, int len)
01117 {return ::send(so, (char *)buf, len, 0);}
01118
01122 inline void endTransmitter(void)
01123 {Socket::endSocket();}
01124
01125
01126
01127
01128
01129
01130 inline SOCKET getTransmitter(void)
01131 {return so;};
01132
01133 public:
01143 inline int Transmit(const char *buffer, size_t len)
01144 {return ::send(so, buffer, len, MSG_DONTWAIT);}
01145
01152 inline bool isOutputReady(unsigned long timeout = 0l)
01153 {return Socket::isPending(SOCKET_PENDING_OUTPUT, timeout);};
01154
01155
01156 inline sockerror_t setRouting(bool enable)
01157 {return Socket::setRouting(enable);};
01158
01159 inline sockerror_t setTypeOfService(socktos_t tos)
01160 {return Socket::setTypeOfService(tos);};
01161
01162 inline sockerror_t setBroadcast(bool enable)
01163 {return Socket::setBroadcast(enable);};
01164 };
01165
01174 class UDPReceive : private UDPSocket
01175 {
01176 protected:
01188 UDPReceive(const InetAddress &bind, tpport_t port);
01189
01198 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01199
01204 sockerror_t Disconnect(void);
01205
01212 bool isPendingReceive(timeout_t timeout)
01213 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01214
01218 inline void endReceiver(void)
01219 {Socket::endSocket();}
01220
01221 inline SOCKET getReceiver(void)
01222 {return so;};
01223
01224 inline sockerror_t setRouting(bool enable)
01225 {return Socket::setRouting(enable);};
01226
01227 public:
01235 inline int Receive(void *buf, size_t len)
01236 {return ::recv(so, (char *)buf, len, 0);};
01237
01244 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
01245 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01246 };
01247
01258 class UDPDuplex : public UDPTransmit, public UDPReceive
01259 {
01260 public:
01269 UDPDuplex(const InetAddress &bind, tpport_t port);
01270
01280 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
01281
01288 sockerror_t Disconnect(void);
01289 };
01290
01291
01316 class TCPSocket : private Socket
01317 {
01318 protected:
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01342 virtual bool OnAccept(const InetHostAddress &ia, tpport_t port)
01343 {return true;};
01344
01345 friend class TCPStream;
01346 friend class SocketPort;
01347 friend class tcpstream;
01348
01349 public:
01361 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01362
01371 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01372 {return Socket::getSender(port);};
01373
01377 void Reject(void);
01378
01382 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01383 {return Socket::getLocal(port);};
01384
01388 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01389 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);}
01390
01394 ~TCPSocket()
01395 {endSocket();};
01396 };
01397
01398
01399
01400
01401
01402
01403
01404
01405 #ifdef _MSC_VER
01406 #pragma warning(disable:4275) // disable C4275 warning
01407 #endif
01408
01422 #if defined(STLPORT) || defined(__KCC)
01423 #define std::iostream std::iostream_withassign
01424 #endif
01425 #ifdef __KCC
01426 using std::iostream;
01427 #endif
01428 class TCPStream : public Socket, public std::streambuf, public std::iostream
01429 {
01430 private:
01431 inline sockerror_t setBroadcast(bool enable)
01432 {return Socket::setBroadcast(enable);};
01433
01434 inline InetHostAddress getSender(tpport_t *port) const
01435 {return InetHostAddress();};
01436
01437 int doallocate();
01438
01439 friend TCPStream& crlf(TCPStream&);
01440 friend TCPStream& lfcr(TCPStream&);
01441
01442 protected:
01443 timeout_t timeout;
01444 int bufsize;
01445 char *gbuf, *pbuf;
01446
01451 TCPStream(bool throwflag = true);
01452
01459 void Allocate(int size);
01460
01465 void endStream(void);
01466
01473 virtual int underflow(void);
01474
01483 int uflow(void);
01484
01492 int overflow(int ch);
01493
01502 void Connect(const InetHostAddress &host, tpport_t port, int size);
01503
01511 std::iostream *tcp(void)
01512 {return ((std::iostream *)this);};
01513
01514 public:
01524 TCPStream(TCPSocket &server, int size = 512, bool throwflag = true, timeout_t timeout = 0);
01525
01536 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512, bool throwflag = true, timeout_t to = 0);
01537
01543 inline void setTimeout(timeout_t to)
01544 {timeout = to;};
01545
01552 TCPStream(const TCPStream &source);
01553
01558 virtual ~TCPStream()
01559 {endStream();};
01560
01567 int sync(void);
01568
01576 bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
01577
01583 int getBufferSize(void) const
01584 {return bufsize;};
01585 };
01586
01595 class tcpstream : public TCPStream
01596 {
01597 public:
01601 tcpstream();
01602
01610 tcpstream(const char *addr, int buffer = 512);
01611
01619 tcpstream(TCPSocket &tcp, int buffer = 512);
01620
01628 void open(const char *addr, int buffer = 512);
01629
01636 void open(TCPSocket &tcp, int buffer = 512);
01637
01641 void close(void);
01642
01646 bool operator!() const;
01647 };
01648
01659 class TCPSession : public TCPStream, public Thread
01660 {
01661 protected:
01674 int WaitConnection(timeout_t timeout = TIMEOUT_INF);
01675
01682 void Initial(void);
01683
01689 void Final(void)
01690 {delete this;};
01691 public:
01703 TCPSession(Semaphore *start, const InetHostAddress &host,
01704 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01705
01717 TCPSession(Semaphore *start, TCPSocket &server, int size = 512,
01718 int pri = 0, int stack = 0);
01719 };
01720
01721 extern __EXPORT std::ostream &operator<<(std::ostream &os, const InetAddress &ia);
01722
01723 inline struct in_addr getaddress(const InetAddress &ia)
01724 {return ia.getAddress();}
01725
01726 #if defined(WIN32)
01727
01741 class init_WSA
01742 {
01743 public:
01744 init_WSA();
01745 private:
01746 WSADATA wsaData;
01747 };
01748
01749 #else // !WIN32
01750
01751 class SocketService;
01752
01772 class SocketPort : public Socket, public TimerPort
01773 {
01774 private:
01775 SocketPort *next, *prev;
01776 SocketService *service;
01777 struct timeval porttimer;
01778 #ifdef __CCXX_USE_POLL
01779 struct pollfd * ufd;
01780 #endif
01781 bool detect_pending;
01782 bool detect_output;
01783 bool detect_disconnect;
01784
01785 friend class SocketService;
01786
01787 protected:
01796 SocketPort(SocketService *svc, TCPSocket &tcp);
01797
01806 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01807
01813 void Attach( SocketService* svc );
01814
01815
01820 virtual ~SocketPort();
01821
01826 void setDetectPending( bool );
01827
01831 bool getDetectPending( void ) const
01832 { return detect_pending; }
01833
01838 void setDetectOutput( bool );
01839
01843 bool getDetectOutput( void ) const
01844 { return detect_output; }
01845
01850 virtual void Expired(void)
01851 {return;};
01852
01857 virtual void Pending(void)
01858 {return;};
01859
01864 virtual void Output(void)
01865 {return;};
01866
01871 virtual void Disconnect(void)
01872 {return;};
01873
01884 sockerror_t Connect(const InetAddress &ia, tpport_t port);
01885
01895 inline int Send(void *buf, int len)
01896 {return ::send(so, (char *)buf, len, 0);};
01897
01906 inline int Recv(void *buf, size_t len)
01907 {return ::recv(so, (char *)buf, len, 0);};
01908
01917 inline int Peek(void *buf, size_t len)
01918 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01919
01920 public:
01928 void setTimer(timeout_t timeout = 0);
01929
01937 void incTimer(timeout_t timeout);
01938 };
01939
01952 class SocketService : public Thread, private Mutex
01953 {
01954 private:
01955 fd_set connect;
01956 int iosync[2];
01957 int hiwater;
01958 int count;
01959 SocketPort *first, *last;
01960
01966 void Attach(SocketPort *port);
01972 void Detach(SocketPort *port);
01973
01977 void Run(void);
01978
01979 friend class SocketPort;
01980
01981 protected:
01987 virtual void OnUpdate(unsigned char buf)
01988 {return;};
01989
01995 virtual void OnEvent(void)
01996 {return;};
01997
02005 virtual void OnCallback(SocketPort *port)
02006 {return;};
02007
02008 public:
02019 void Update(unsigned char flag = 0xff);
02020
02027 SocketService(int pri = 0);
02028
02033 ~SocketService();
02034
02041 inline int getCount(void) const
02042 {return count;};
02043 };
02044
02045 #ifdef __CCXX_NAMESPACE_H__
02046 #undef __CCXX_NAMESPACE_H__
02047 #include <cc++/namespace.h>
02048 #endif
02049
02050 #endif // !WIN32
02051
02052 #endif
02053