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 #ifndef __CCXX_THREAD_H__
00045 #include <cc++/thread.h>
00046 #else
00047 #ifdef __CCXX_NAMESPACE_H__
00048 #include <cc++/macros.h>
00049 #endif
00050 #endif
00051
00052 #include <iostream.h>
00053
00054 typedef enum
00055 {
00056 SOCKET_COMPLETION_IMMEDIATE,
00057 SOCKET_COMPLETION_DELAYED
00058 } sockcomplete_t;
00059
00060 typedef enum
00061 {
00062 SOCKET_INITIAL,
00063 SOCKET_AVAILABLE,
00064 SOCKET_BOUND,
00065 SOCKET_CONNECTED,
00066 SOCKET_CONNECTING
00067 } sockstate_t;
00068
00069 typedef enum
00070 {
00071 SOCKET_SUCCESS=0,
00072 SOCKET_CREATE_FAILED,
00073 SOCKET_COPY_FAILED,
00074 SOCKET_INPUT_ERROR,
00075 SOCKET_INPUT_INTERRUPT,
00076 SOCKET_RESOURCE_FAILURE,
00077 SOCKET_OUTPUT_ERROR,
00078 SOCKET_OUTPUT_INTERRUPT,
00079 SOCKET_NOT_CONNECTED,
00080 SOCKET_CONNECT_REFUSED,
00081 SOCKET_CONNECT_REJECTED,
00082 SOCKET_CONNECT_TIMEOUT,
00083 SOCKET_CONNECT_FAILED,
00084 SOCKET_CONNECT_INVALID,
00085 SOCKET_CONNECT_BUSY,
00086 SOCKET_CONNECT_NOROUTE,
00087 SOCKET_BINDING_FAILED,
00088 SOCKET_BROADCAST_DENIED,
00089 SOCKET_ROUTING_DENIED,
00090 SOCKET_KEEPALIVE_DENIED,
00091 SOCKET_SERVICE_DENIED,
00092 SOCKET_SERVICE_UNAVAILABLE,
00093 SOCKET_EXTENDED_ERROR
00094 } sockerror_t;
00095
00096 typedef enum
00097 {
00098 SOCKET_IPTOS_LOWDELAY,
00099 SOCKET_IPTOS_THROUGHPUT,
00100 SOCKET_IPTOS_RELIABILITY,
00101 SOCKET_IPTOS_MINCOST,
00102 SOCKET_IPTOS_INVALID
00103 } socktos_t;
00104
00105 typedef enum
00106 {
00107 SOCKET_PENDING_INPUT,
00108 SOCKET_PENDING_OUTPUT,
00109 SOCKET_PENDING_ERROR
00110 } sockpend_t;
00111
00115 typedef unsigned short tpport_t;
00116
00117 class InetHostAddress;
00118 class InetMaskAddress;
00119
00134 class InetAddress
00135 {
00136 protected:
00137 struct in_addr ipaddr;
00138 static Mutex mutex;
00139
00145 void setAddress(const char *address);
00146
00147 public:
00152 InetAddress();
00153
00161 InetAddress(struct in_addr);
00162
00169 InetAddress(const char *address);
00170
00177 const char *getHostname(void) const;
00178
00186 bool isInetAddress(void) const;
00187
00195 inline struct in_addr getAddress(void) const
00196 {return ipaddr;};
00197
00198 InetAddress &operator=(const char *str);
00199 InetAddress &operator=(struct in_addr addr);
00200
00201 inline bool operator!() const
00202 {return !isInetAddress();};
00203
00208 bool operator==(const InetAddress &a) const;
00209
00215 bool operator!=(const InetAddress &a) const;
00216 };
00217
00230 class InetMaskAddress : public InetAddress
00231 {
00232 public:
00239 InetMaskAddress(const char *mask);
00240
00251 friend InetHostAddress operator&(const InetHostAddress &addr,
00252 const InetMaskAddress &mask);
00253 };
00254
00262 class InetHostAddress : public InetAddress
00263 {
00264 public:
00270 InetHostAddress();
00271
00281 InetHostAddress(const char *host);
00282
00290 InetHostAddress(struct in_addr addr);
00291
00292
00297 InetHostAddress &operator&=(const InetMaskAddress &mask);
00298
00299 friend class InetMaskAddress;
00300 friend InetHostAddress operator&(const InetHostAddress &addr,
00301 const InetMaskAddress &mask);
00302 };
00303
00308 class BroadcastAddress : public InetAddress
00309 {
00310 public:
00318 BroadcastAddress(const char *net = "255.255.255.255");
00319 };
00320
00338 class Socket
00339 {
00340 private:
00341
00342 mutable sockerror_t errid;
00343 mutable const char *errstr;
00344
00345 mutable struct
00346 {
00347 bool thrown: 1;
00348 bool broadcast: 1;
00349 bool route: 1;
00350 bool keepalive: 1;
00351 } flags;
00352
00353 void setSocket(void);
00354
00355 protected:
00356 sockstate_t state;
00357 int so;
00358
00366 sockerror_t Error(sockerror_t error, char *errstr = NULL) const;
00367
00374 inline void Error(char *estr)
00375 {Error(SOCKET_EXTENDED_ERROR, estr);};
00376
00383 inline void setError(bool enable)
00384 {flags.thrown = !enable;};
00385
00391 void endSocket(void);
00392
00398 sockerror_t connectError(void);
00399
00408 sockerror_t setBroadcast(bool enable);
00409
00417 sockerror_t setRouting(bool enable);
00418
00430 Socket(int domain, int type, int protocol = 0);
00431
00439 Socket(int fd);
00440
00448 Socket(const Socket &source);
00449
00450 public:
00458 virtual ~Socket()
00459 {endSocket();};
00460
00464 Socket &operator=(const Socket &from);
00465
00475 InetHostAddress getSender(tpport_t *port = NULL) const;
00476
00486 InetHostAddress getPeer(tpport_t *port = NULL) const;
00487
00495 InetHostAddress getLocal(tpport_t *port = NULL) const;
00496
00507 void setCompletion(sockcomplete_t completion);
00508
00516 sockerror_t setKeepAlive(bool enable);
00517
00526 sockerror_t setTypeOfService(socktos_t service);
00527
00536 bool isConnected(void) const;
00537
00545 bool isActive(void) const;
00546
00551 bool operator!() const;
00552
00559 inline bool isBroadcast(void) const
00560 {return flags.broadcast;};
00561
00567 inline bool isRouted(void) const
00568 {return flags.route;};
00569
00576 inline sockerror_t getErrorNumber(void) const
00577 {return errid;};
00578
00585 inline const char *getErrorString(void) const
00586 {return errstr;};
00587
00597 virtual bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
00598 };
00599
00632 class UDPSocket : public Socket
00633 {
00634 private:
00635 inline sockerror_t setKeepAlive(bool enable)
00636 {return Socket::setKeepAlive(enable);};
00637
00638 protected:
00639 struct sockaddr_in peer;
00640
00641 public:
00645 UDPSocket(void);
00646
00656 UDPSocket(const InetAddress &bind, tpport_t port);
00657
00661 ~UDPSocket()
00662 {endSocket();};
00663
00671 void setPeer(const InetHostAddress &host, tpport_t port);
00672
00680 inline int Send(void *buf, size_t len)
00681 {return ::sendto(so, (char *)buf, len, 0, (struct sockaddr *)&peer, (socklen_t)sizeof(peer));};
00682
00690 inline int Recv(void *buf, size_t len)
00691 {return ::recv(so, (char *)buf, len, 0);};
00692
00701 InetHostAddress getPeer(tpport_t *port = NULL);
00702
00710 inline int Peek(void *buf, size_t len)
00711 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
00712 };
00713
00714
00723 class UDPBroadcast : public UDPSocket
00724 {
00725 private:
00726 void setPeer(const InetHostAddress &ia, tpport_t port) {};
00727
00728 sockerror_t setBroadcast(bool enable)
00729 {return Socket::setBroadcast(enable);};
00730
00731 public:
00738 UDPBroadcast(const InetAddress &ia, tpport_t port);
00739
00746 void setPeer(const BroadcastAddress &ia, tpport_t port);
00747 };
00748
00757 class UDPTransmit : private UDPSocket
00758 {
00759 protected:
00763 UDPTransmit();
00764
00777 UDPTransmit(const InetAddress &bind, tpport_t port = 5005);
00778
00787 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
00788
00797 sockerror_t Connect(const BroadcastAddress &subnet, tpport_t port);
00798
00803 sockerror_t Disconnect(void);
00804
00812 inline int Send(void *buf, int len)
00813 {return ::send(so, (char *)buf, len, 0);};
00814
00818 inline void endTransmit(void)
00819 {Socket::endSocket();};
00820
00821 00822 00823 00824 00825
00826 inline int getTransmitter(void)
00827 {return so;};
00828
00829 public:
00833 inline int Transmit(unsigned char *buffer, size_t len)
00834 {return ::send(so, buffer, len, MSG_DONTWAIT);};
00835
00836 inline sockerror_t setRouting(bool enable)
00837 {return Socket::setRouting(enable);};
00838
00839 inline sockerror_t setTypeOfService(socktos_t tos)
00840 {return Socket::setTypeOfService(tos);};
00841
00842 inline sockerror_t setBroadcast(bool enable)
00843 {return Socket::setBroadcast(enable);};
00844 };
00845
00854 class UDPReceive : private UDPSocket
00855 {
00856 protected:
00868 UDPReceive(const InetAddress &bind, tpport_t port);
00869
00878 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
00879
00884 sockerror_t Disconnect(void);
00885
00889 inline void endReceiver(void)
00890 {Socket::endSocket();};
00891
00892 inline int getReceiver(void)
00893 {return so;};
00894
00895 public:
00903 inline int Receive(void *buf, size_t len)
00904 {return ::recv(so, (char *)buf, len, 0);};
00905
00912 inline bool isInputReady(timeout_t timeout = TIMEOUT_INF)
00913 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
00914 };
00915
00926 class UDPDuplex : public UDPTransmit, public UDPReceive
00927 {
00928 public:
00937 UDPDuplex(const InetAddress &bind, tpport_t port);
00938
00948 sockerror_t Connect(const InetHostAddress &host, tpport_t port);
00949
00956 sockerror_t Disconnect(void);
00957 };
00958
00959
00985 class TCPSocket : private Socket
00986 {
00987 protected:
00995 virtual bool OnAccept(const InetHostAddress &ia, short port) {
00996 return false;
00997 }
00998
01010 virtual bool OnAccept(const InetHostAddress &ia, tpport_t port)
01011 {return true;};
01012
01013 friend class TCPStream;
01014 friend class SocketPort;
01015 friend class tcpstream;
01016
01017 public:
01029 TCPSocket(const InetAddress &bind, tpport_t port, int backlog = 5);
01030
01039 inline InetHostAddress getRequest(tpport_t *port = NULL) const
01040 {return Socket::getSender(port);};
01041
01045 void Reject(void);
01046
01050 inline InetHostAddress getLocal(tpport_t *port = NULL) const
01051 {return Socket::getLocal(port);};
01052
01056 inline bool isPendingConnection(timeout_t timeout = TIMEOUT_INF)
01057 {return Socket::isPending(SOCKET_PENDING_INPUT, timeout);};
01058
01062 ~TCPSocket()
01063 {endSocket();};
01064 };
01065
01080 class TCPStream : public streambuf, public iostream, public Socket
01081 {
01082 private:
01083 inline sockerror_t setBroadcast(bool enable)
01084 {return Socket::setBroadcast(enable);};
01085
01086 inline InetHostAddress getSender(tpport_t *port) const
01087 {return InetHostAddress();};
01088
01089 int doallocate();
01090
01091 friend TCPStream& crlf(TCPStream&);
01092 friend TCPStream& lfcr(TCPStream&);
01093
01094 protected:
01095 int bufsize;
01096 char *gbuf, *pbuf;
01097
01102 TCPStream();
01103
01110 void Allocate(int size);
01111
01116 void endStream(void);
01117
01124 int underflow(void);
01125
01134 int uflow(void);
01135
01143 int overflow(int ch);
01144
01152 iostream *tcp(void)
01153 {return ((iostream *)this);};
01154
01155 public:
01163 TCPStream(TCPSocket &server, int size = 512);
01164
01173 TCPStream(const InetHostAddress &host, tpport_t port, int size = 512);
01174
01181 TCPStream(const TCPStream &source);
01182
01187 ~TCPStream()
01188 {endStream();};
01189
01196 int sync(void);
01197
01205 bool isPending(sockpend_t pend, timeout_t timeout = TIMEOUT_INF);
01206
01212 int getBufferSize(void) const
01213 {return bufsize;};
01214 };
01215
01224 class tcpstream : public TCPStream
01225 {
01226 public:
01230 tcpstream();
01231
01239 tcpstream(const char *addr, int buffer = 512);
01240
01248 tcpstream(TCPSocket &tcp, int buffer = 512);
01249
01257 void open(const char *addr, int buffer = 512);
01258
01265 void open(TCPSocket &tcp, int buffer = 512);
01266
01270 void close(void);
01271
01275 bool operator!() const;
01276 };
01277
01288 class TCPSession : public TCPStream, public Thread
01289 {
01290 protected:
01303 int WaitConnection(timeout_t timeout = TIMEOUT_INF);
01304
01311 void Initial(void);
01312
01318 void Final(void)
01319 {delete this;};
01320 public:
01332 TCPSession(Semaphore *start, const InetHostAddress &host,
01333 tpport_t port, int size = 512, int pri = 0, int stack = 0);
01334
01346 TCPSession(Semaphore *start, TCPSocket &server, int size = 512,
01347 int pri = 0, int stack = 0);
01348 };
01349
01350 class SocketPort;
01351 class SocketService;
01352
01372 class SocketPort : public Socket, public TimerPort
01373 {
01374 private:
01375 SocketPort *next, *prev;
01376 SocketService *service;
01377 struct timeval porttimer;
01378 #ifdef __CCXX_USE_POLL
01379 struct pollfd * ufd;
01380 #endif
01381 bool detect_pending;
01382 bool detect_output;
01383 bool detect_disconnect;
01384
01385 friend class SocketService;
01386
01387 protected:
01396 SocketPort(SocketService *svc, TCPSocket &tcp);
01397
01406 SocketPort(SocketService *svc, const InetAddress &ia, tpport_t port);
01407
01413 void Attach( SocketService* svc );
01414
01415
01420 virtual ~SocketPort();
01421
01426 void setDetectPending( bool );
01427
01431 bool getDetectPending( void ) const
01432 { return detect_pending; }
01433
01438 void setDetectOutput( bool );
01439
01443 bool getDetectOutput( void ) const
01444 { return detect_output; }
01445
01450 virtual void Expired(void)
01451 {return;};
01452
01457 virtual void Pending(void)
01458 {return;};
01459
01464 virtual void Output(void)
01465 {return;};
01466
01471 virtual void Disconnect(void)
01472 {return;};
01473
01484 sockerror_t Connect(const InetAddress &ia, tpport_t port);
01485
01495 inline int Send(void *buf, int len)
01496 {return ::send(so, (char *)buf, len, 0);};
01497
01506 inline int Recv(void *buf, size_t len)
01507 {return ::recv(so, (char *)buf, len, 0);};
01508
01517 inline int Peek(void *buf, size_t len)
01518 {return ::recv(so, (char *)buf, len, MSG_PEEK);};
01519
01520 public:
01528 void setTimer(timeout_t timeout = 0);
01529
01537 void incTimer(timeout_t timeout);
01538 };
01539
01552 class SocketService : public Thread, private Mutex
01553 {
01554 private:
01555 fd_set connect;
01556 int iosync[2];
01557 int hiwater;
01558 int count;
01559 SocketPort *first, *last;
01560
01566 void Attach(SocketPort *port);
01572 void Detach(SocketPort *port);
01573
01577 void Run(void);
01578
01579 friend class SocketPort;
01580
01581 protected:
01587 virtual void OnUpdate(unsigned char buf)
01588 {return;};
01589
01595 virtual void OnEvent(void)
01596 {return;};
01597
01605 virtual void OnCallback(SocketPort *port)
01606 {return;};
01607
01608 public:
01619 void Update(unsigned char flag = 0xff);
01620
01627 SocketService(int pri = 0);
01628
01633 ~SocketService();
01634
01641 inline int getCount(void) const
01642 {return count;};
01643 };
01644
01645 ostream &operator<<(ostream &os, const InetAddress &ia);
01646
01647 inline struct in_addr getaddress(const InetAddress &ia)
01648 {return ia.getAddress();};
01649
01650 #ifdef __CCXX_NAMESPACE_H__
01651 #undef __CCXX_NAMESPACE_H__
01652 #include <cc++/namespace.h>
01653 #endif
01654
01655 #endif
01656