fastdo  0.5.12
eiennet_socket.hpp
浏览该文件的文档.
1 #ifndef __SOCKET_HPP__
2 #define __SOCKET_HPP__
3 
4 namespace eiennet
5 {
6 //#define SOCKET_EXCEPTION_USE // 错误机制是使用错误异常机制,还是使用传统返回值模式
7 
10 {
11 public:
12  SocketLib();
13  ~SocketLib();
14 private:
17 };
18 
21 {
22 public:
23  SocketError( int errType, winux::AnsiString const & errStr ) : winux::Error( errType, errStr ) { }
24 };
25 
28 {
29 public:
30  EndPoint() { }
31  virtual ~EndPoint() { }
32 
34  virtual void * get() const = 0;
36  virtual winux::uint & size() const = 0;
38  virtual winux::String toString() const = 0;
39 };
40 
43 {
44 public:
45 
46  // classes and types ------------------------------------------------------------------
47  enum AddrFamily {
48  afUnspec = 0, /* Unspecified. */
49  afLocal = 1, /* Local to host (pipes and file-domain). */
50  afUnix = afLocal, /* POSIX name for PF_LOCAL. */
51  afFile = afLocal, /* Another non-standard name for PF_LOCAL. */
52  afInet = 2, /* IP protocol family. */
53  afAx25 = 3, /* Amateur Radio AX.25. */
54  afIpx = 4, /* Novell Internet Protocol. */
55  afAppletalk = 5, /* Appletalk DDP. */
56  afNetrom = 6, /* Amateur radio NetROM. */
57  afBridge = 7, /* Multiprotocol bridge. */
58  afAtmpvc = 8, /* ATM PVCs. */
59  afX25 = 9, /* Reserved for X.25 project. */
60  afInet6 = 10, /* IP version 6. */
61  afRose = 11, /* Amateur Radio X.25 PLP. */
62  afDecnet = 12, /* Reserved for DECnet project. */
63  afNetbeui = 13, /* Reserved for 802.2LLC project. */
64  afSecurity = 14, /* Security callback pseudo AF. */
65  afKey = 15, /* PF_KEY key management API. */
66  afNetlink = 16,
67  afRoute = afNetlink, /* Alias to emulate 4.4BSD. */
68  afPacket = 17, /* Packet family. */
69  afAsh = 18, /* Ash. */
70  afEconet = 19, /* Acorn Econet. */
71  afAtmsvc = 20, /* ATM SVCs. */
72  afRds = 21, /* RDS sockets. */
73  afSna = 22, /* Linux SNA Project */
74  afIrda = 23, /* IRDA sockets. */
75  afPppox = 24, /* PPPoX sockets. */
76  afWanpipe = 25, /* Wanpipe API sockets. */
77  afLlc = 26, /* Linux LLC. */
78  afUnknown27 = 27,
79  afUnknown28 = 28,
80  afCan = 29, /* Controller Area Network. */
81  afTipc = 30, /* TIPC sockets. */
82  afBluetooth = 31, /* Bluetooth sockets. */
83  afIucv = 32, /* IUCV sockets. */
84  afRxrpc = 33, /* RxRPC sockets. */
85  afIsdn = 34, /* mISDN sockets. */
86  afPhonet = 35, /* Phonet sockets. */
87  afIeee802154 = 36, /* IEEE 802.15.4 sockets. */
88  afMax = 37 /* For now.. */
89  };
90 
91  enum SockType {
93  sockStream, /* Sequenced, reliable, connection-based byte streams. */
94  sockDatagram, /* Connectionless, unreliable datagrams of fixed maximum length. */
95  sockRaw, /* Raw protocol interface. */
96  sockRdm, /* Reliably-delivered messages. */
97  sockSeqPacket, /* Sequenced, reliable, connection-based, datagrams of fixed maximum length. */
98  sockDccp, /* Datagram Congestion Control Protocol. */
99  sockPacket, /* Linux specific way of getting packets at the dev level. For writing rarp and
100  other similar things on the user level. */
101 
102  /* Flags to be ORed into the type parameter of socket and socketpair and used for the flags parameter of paccept. */
103 
104  sockCloexec, /* Atomically set close-on-exec flag for the new descriptor(s). */
105  sockNonblock /* Atomically mark descriptor(s) as non-blocking. */
106  };
107 
108  enum Protocol {
109  protoIp = 0, /* Dummy protocol for TCP. */
110  protoIcmp, /* Internet Control Message Protocol. */
111  protoIgmp, /* Internet Group Management Protocol. */
112  protoIpip, protoIpv4 = protoIpip, /* IPIP tunnels (older KA9Q tunnels use 94). */
113  protoTcp, /* Transmission Control Protocol. */
114  protoEgp, /* Exterior Gateway Protocol. */
115  protoPup, /* PUP protocol. */
116  protoUdp, /* User Datagram Protocol. */
117  protoIdp, /* XNS IDP protocol. */
118  protoTp, /* SO Transport Protocol Class 4. */
119  protoDccp, /* Datagram Congestion Control Protocol. */
120  protoIpv6, /* IPv6 header. */
121  protoRsvp, /* Reservation Protocol. */
122  protoGre, /* General Routing Encapsulation. */
123  protoEsp, /* encapsulating security payload. */
124  protoAh, /* authentication header. */
125  protoMtp, /* Multicast Transport Protocol. */
126  protoBeetph, /* IP option pseudo header for BEET. */
127  protoEncap, /* Encapsulation Header. */
128  protoPim, /* Protocol Independent Multicast. */
129  protoComp, /* Compression Header Protocol. */
130  protoSctp, /* Stream Control Transmission Protocol. */
131  protoUdplite, /* UDP-Lite protocol. */
132  protoRaw, /* Raw IP packets. */
133  protoMax
134  };
135 
136 public:
137  // static members ---------------------------------------------------------------------
138  // send/recv's message flags
139  static int const MsgDefault;
140 #if defined(_MSC_VER) || defined(WIN32)
141  static int const MsgOob;
142  static int const MsgPeek;
143  static int const MsgDontRoute;
144  static int const MsgWaitAll;
145  static int const MsgPartial;
146  static int const MsgInterrupt;
147  static int const MsgMaxIovLen;
148 #else
149  static int const MsgOob;
150  static int const MsgPeek;
151  static int const MsgDontRoute;
152 # ifdef __USE_GNU
153  /* DECnet uses a different name. */
154  static int const MsgTryHard;
155 # endif
156  static int const MsgCTrunc;
157  static int const MsgProxy;
158  static int const MsgTrunc;
159  static int const MsgDontWait;
160  static int const MsgEor;
161  static int const MsgWaitAll;
162  static int const MsgFin;
163  static int const MsgSyn;
164  static int const MsgConfirm;
165  static int const MsgRst;
166  static int const MsgErrQueue;
167  static int const MsgNoSignal;
168  static int const MsgMore;
169  static int const MsgWaitForOne;
170  static int const MsgCMsgCloexec;
171 
172 #endif
173  // shutdown's how flags
174  static int const SdReceive;
175  static int const SdSend;
176  static int const SdBoth;
177 
178  typedef std::function< void ( int hadBytes, void * param ) > FunctionSuccessCallback;
179 public:
180  // constructor/destructor -------------------------------------------------------------
181 
186  explicit Socket( int sock = -1, bool isNewSock = false );
187 
189  Socket( AddrFamily af, SockType sockType, Protocol proto );
190 
191 #ifndef MOVE_SEMANTICS_DISABLED
192 
193  Socket( Socket && other );
195  Socket & operator = ( Socket && other );
196 #endif
197 
198  virtual ~Socket();
199 
200 public:
201  // methods ----------------------------------------------------------------------------
202 
204  bool create( AddrFamily af, SockType sockType, Protocol proto );
205 
207  int close();
208 
212  int shutdown( int how = SdReceive );
213 
215  int send( void const * data, int size, int msgFlags = MsgDefault );
217  int send( winux::AnsiString const & data, int msgFlags = MsgDefault ) { return this->send( data.c_str(), (int)data.size(), msgFlags ); }
219  int send( winux::Buffer const & data, int msgFlags = MsgDefault ) { return this->send( data.getBuf(), (int)data.getSize(), msgFlags ); }
220 
224  bool sendUntil( int targetSize, void const * data, int msgFlags = MsgDefault );
225  bool sendUntil( winux::AnsiString const & data, int msgFlags = MsgDefault ) { return this->sendUntil( (int)data.size(), data.c_str(), msgFlags ); }
226  bool sendUntil( winux::Buffer const & data, int msgFlags = MsgDefault ) { return this->sendUntil( (int)data.getSize(), data.getBuf(), msgFlags ); }
227 
235  int sendWaitUntil( int targetSize, void const * data, int * hadSent, double sec, int * rcWait, FunctionSuccessCallback eachSuccessCallback = FunctionSuccessCallback(), void * param = nullptr, int msgFlags = MsgDefault );
236  int sendWaitUntil( winux::AnsiString const & data, int * hadSent, double sec, int * rcWait, FunctionSuccessCallback eachSuccessCallback = FunctionSuccessCallback(), void * param = nullptr, int msgFlags = MsgDefault )
237  { return this->sendWaitUntil( (int)data.size(), data.c_str(), hadSent, sec, rcWait, std::move(eachSuccessCallback), param, msgFlags ); }
238  int sendWaitUntil( winux::Buffer const & data, int * hadSent, double sec, int * rcWait, FunctionSuccessCallback eachSuccessCallback = FunctionSuccessCallback(), void * param = nullptr, int msgFlags = MsgDefault )
239  { return this->sendWaitUntil( (int)data.getSize(), data.getBuf(), hadSent, sec, rcWait, std::move(eachSuccessCallback), param, msgFlags ); }
240 
242  template < typename _PodType >
243  bool sendUntilType( _PodType const & v, int msgFlags = MsgDefault ) { return this->sendUntil( sizeof(_PodType), &v, msgFlags ); }
244 
246  int recv( void * buf, int size, int msgFlags = MsgDefault );
247 
254  winux::Buffer recv( int size, int msgFlags = MsgDefault );
255 
259  bool recvUntilTarget( winux::AnsiString const & target, winux::GrowBuffer * data, winux::GrowBuffer * extraData, int msgFlags = MsgDefault );
260 
269  int recvWaitUntilTarget( winux::AnsiString const & target, winux::GrowBuffer * data, winux::GrowBuffer * extraData, int * hadRead, int * startpos, int * pos, double sec, int * rcWait, FunctionSuccessCallback eachSuccessCallback = FunctionSuccessCallback(), void * param = nullptr, int msgFlags = MsgDefault );
270 
274  bool recvUntilSize( int targetSize, winux::GrowBuffer * data, int msgFlags = MsgDefault );
275 
283  int recvWaitUntilSize( int targetSize, winux::GrowBuffer * data, int * hadRead, double sec, int * rcWait, FunctionSuccessCallback eachSuccessCallback = FunctionSuccessCallback(), void * param = nullptr, int msgFlags = MsgDefault );
284 
286  template < typename _PodType >
287  bool recvUntilType( _PodType * v, int msgFlags = MsgDefault )
288  {
289  winux::GrowBuffer data;
290  data.setBuf( v, 0, sizeof(_PodType), true );
291  return this->recvUntilSize( sizeof(_PodType), &data, msgFlags );
292  }
293 
300  winux::Buffer recvAvail( int msgFlags = MsgDefault );
301 
310  winux::Buffer recvWaitAvail( double sec, int * rcWait, int msgFlags = MsgDefault );
311 
313  int sendTo( EndPoint const & ep, void const * data, int size, int msgFlags = MsgDefault );
315  int recvFrom( EndPoint * ep, void * buf, int size, int msgFlags = MsgDefault );
316 
318  bool connect( EndPoint const & ep );
319 
321  bool bind( EndPoint const & ep );
322 
324  bool listen( int backlog );
325 
329  bool accept( int * sock, EndPoint * ep = NULL );
330 
333  {
334  int sock;
335  return this->accept( &sock, ep ) ? winux::SharedPointer<Socket>( new Socket( sock, true ) ) : winux::SharedPointer<Socket>();
336  }
337 
338  // socket's options -------------------------------------------------------------------
339 
341  int getRecvBufSize() const;
343  bool setRecvBufSize( int optval );
344 
346  int getSendBufSize() const;
348  bool setSendBufSize( int optval );
349 
351  winux::uint32 getRecvTimeout() const;
353  bool setRecvTimeout( winux::uint32 optval );
354 
356  winux::uint32 getSendTimeout() const;
360  bool setSendTimeout( winux::uint32 optval );
361 
363  bool getReUseAddr() const;
365  bool setReUseAddr( bool optval );
366 
368  bool getBroadcast() const;
370  bool setBroadcast( bool optval );
371 
373  int getError() const;
374 
376  SockType getType() const;
377 
381  bool isListening() const;
382 
383  // ioctls -----------------------------------------------------------------------------
384 
386  int getAvailable() const;
387 
389  bool setBlocking( bool blocking );
390 
391  // attributes -------------------------------------------------------------------------
392 
394  int get() const;
395 
397  operator bool() const { return this->get() > -1; }
398 
399  // static -----------------------------------------------------------------------------
400 
402  static int ErrNo();
403 
404 protected:
407 };
408 
411 {
412  enum { RetryCount = 10 }; // 默认重试次数
413 
415  winux::GrowBuffer extraData; // 额外数据
416  int startpos; // 起始位置
417  int pos; // 找到位置
418  int hadBytes; // 已接收/发送数据量
419  int targetBytes; // 目标数据量
420  int retryCount; // 已重试次数
421 
423  {
424  this->resetStatus();
425  }
426 
427  void resetData()
428  {
429  this->data.free();
430  this->extraData.free();
431  }
432 
433  void resetStatus()
434  {
435  this->startpos = 0;
436  this->pos = -1;
437  this->hadBytes = 0;
438  this->targetBytes = 0;
439  this->retryCount = 0;
440  }
441 };
442 
444 
445 class EIENNET_DLL SocketStreamBuf : public std::streambuf
446 {
447 public:
449  eiennet::Socket * sock,
450  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out,
451  winux::uint32 inputBufSize = (winux::uint32)-1,
452  winux::uint32 outputBufSize = (winux::uint32)-1
453  );
454 
455  virtual ~SocketStreamBuf();
456 
457  Socket * getSocket() const { return _sock; }
458  // input buffer begin -----------------------------------------------------------------------
459 protected:
460  virtual int_type underflow();
461  // input buffer end -----------------------------------------------------------------------
462 
463  // output buffer begin -----------------------------------------------------------------------
464 protected:
465  virtual int_type overflow( int_type c );
466  virtual int sync();
467  int _flush();
468  // output buffer end -----------------------------------------------------------------------
469 
470 
471 private:
472  eiennet::Socket * _sock;
473  winux::Buffer _inputBuf;
474  winux::Buffer _outputBuf;
475 
477 };
478 
479 class EIENNET_DLL SocketStreamOut : public std::ostream
480 {
481 private:
482  SocketStreamBuf * _sockBuf;
483 public:
484  SocketStreamOut( SocketStreamBuf * sockBuf ) : std::ostream(sockBuf), _sockBuf(sockBuf) { }
485  SocketStreamOut( SocketStreamBuf & sockBuf ) : std::ostream(&sockBuf), _sockBuf(&sockBuf) { }
486  SocketStreamOut( winux::SimplePointer<SocketStreamBuf> & sockBuf ) : std::ostream(sockBuf.get()), _sockBuf(sockBuf.get()) { }
487  SocketStreamOut( winux::SharedPointer<SocketStreamBuf> & sockBuf ) : std::ostream(sockBuf.get()), _sockBuf(sockBuf.get()) { }
488 
489  SocketStreamOut & writeAndFlush( winux::Buffer const & data );
490 };
491 
492 class EIENNET_DLL SocketStreamIn : public std::istream
493 {
494 private:
495  SocketStreamBuf * _sockBuf;
496 public:
497  SocketStreamIn( SocketStreamBuf * sockBuf ) : std::istream(sockBuf), _sockBuf(sockBuf) { }
498  SocketStreamIn( SocketStreamBuf & sockBuf ) : std::istream(&sockBuf), _sockBuf(&sockBuf) { }
499  SocketStreamIn( winux::SimplePointer<SocketStreamBuf> & sockBuf ) : std::istream(sockBuf.get()), _sockBuf(sockBuf.get()) { }
500  SocketStreamIn( winux::SharedPointer<SocketStreamBuf> & sockBuf ) : std::istream(sockBuf.get()), _sockBuf(sockBuf.get()) { }
501 
502  std::streamsize getAvailable() const;
503  SocketStreamIn & readAvail( winux::Buffer * data );
504  SocketStreamIn & read( winux::Buffer * data, std::streamsize size );
506  std::streamsize waitAvail( double sec );
507 };
508 
510 
511 namespace ip
512 {
513 
516 {
517 public:
519  EndPoint();
521  EndPoint( winux::Mixed const & ipAndPort );
523  EndPoint( winux::String const & ipAddr, winux::ushort port );
524  EndPoint( EndPoint const & other );
525  virtual ~EndPoint();
526  EndPoint & operator = ( EndPoint const & other );
527 
529  virtual void * get() const;
531  virtual winux::uint & size() const;
532  virtual winux::String toString() const;
533 
535  operator winux::Mixed() const;
536 private:
538 };
539 
542 {
543 public:
544  typedef std::vector<ip::EndPoint> EndPointArray;
546  Resolver( winux::Mixed const & hostAndPort );
548  Resolver( winux::String const & hostName, winux::ushort port );
549 
550  EndPointArray::iterator begin() { return _epArr.begin(); }
551  EndPointArray::const_iterator begin() const { return _epArr.begin(); }
552  EndPointArray::iterator end() { return _epArr.end(); }
553  EndPointArray::const_iterator end() const { return _epArr.end(); }
554 
556  int count() const { return (int)_epArr.size(); }
558  winux::String const & getHostname() const { return _hostName; }
560  winux::ushort getPort() const { return _port; }
561 
562  EndPointArray::value_type const & operator [] ( int i ) const { return _epArr[i]; }
563  EndPointArray::value_type & operator [] ( int i ) { return _epArr[i]; }
564 
565  EndPointArray & getArr() { return _epArr; }
566  EndPointArray const & getArr() const { return _epArr; }
567 
569  operator winux::Mixed() const;
570 private:
571  int _resolve( winux::String const & hostName, winux::ushort port );
572  winux::String _hostName;
573  winux::ushort _port;
574  EndPointArray _epArr;
575 };
576 
577 namespace tcp
578 {
581 {
582 public:
584 
589  explicit Socket( int sock, bool isNewSock = false ) : BaseClass( sock, isNewSock ) { }
590 
592  Socket() : BaseClass( BaseClass::afInet, BaseClass::sockStream, BaseClass::protoTcp ) { }
593 
594 #ifndef MOVE_SEMANTICS_DISABLED
595 
596  Socket( Socket && other ) : BaseClass( std::move(other) ) { }
598  Socket & operator = ( Socket && other )
599  {
600  BaseClass::operator = ( std::move(other) );
601  return *this;
602  }
603 #endif
604 
605  bool connect( winux::String const & ipAddr, winux::ushort port )
606  {
607  return BaseClass::connect( EndPoint( ipAddr, port ) );
608  }
609 
610  bool bind( winux::String const & ipAddr, winux::ushort port )
611  {
612  return BaseClass::bind( EndPoint( ipAddr, port ) );
613  }
614 
617  {
618  int sock;
619  return BaseClass::accept( &sock, ep ) ? winux::SharedPointer<Socket>( new Socket( sock, true ) ) : winux::SharedPointer<Socket>();
620  }
621 };
622 
624 EIENNET_FUNC_DECL(int) ConnectAttempt( Socket * sock, EndPoint const & ep, winux::uint32 timeoutMs );
625 
632 EIENNET_FUNC_DECL(int) ConnectAttempt( Socket * sock, Resolver const & resolver, winux::uint32 perCnnTimeoutMs );
633 
634 } // namespace tcp
635 
636 namespace udp
637 {
640 {
641 public:
643 
648  explicit Socket( int sock, bool isNewSock = false ) : BaseClass( sock, isNewSock ) { }
649 
651  Socket() : BaseClass( BaseClass::afInet, BaseClass::sockDatagram, BaseClass::protoUdp ) { }
652 
653 #ifndef MOVE_SEMANTICS_DISABLED
654 
655  Socket( Socket && other ) : BaseClass( std::move(other) ) { }
657  Socket & operator = ( Socket && other )
658  {
659  BaseClass::operator = ( std::move(other) );
660  return *this;
661  }
662 #endif
663 
664  int sendTo( winux::String const & ipAddr, winux::ushort port, void const * data, int size, int msgFlags = MsgDefault )
665  {
666  return BaseClass::sendTo( EndPoint( ipAddr, port ), data, size, msgFlags );
667  }
668 
669  int recvFrom( winux::String * ipAddr, winux::ushort * port, void * buf, int size, int msgFlags = MsgDefault );
670 };
671 
672 } // namespace udp
673 
674 } // namespace ip
675 
677 
678 namespace io
679 {
680 
683 {
684 public:
685  SelectRead();
686  SelectRead( Socket const & sock );
687  SelectRead( Socket const * sock );
688  SelectRead( int fd );
689  SelectRead( winux::Mixed const & fds );
690  ~SelectRead();
691 
692  SelectRead & setReadSock( Socket const & sock ) { return setReadFd( sock.get() ); }
693  SelectRead & setReadSock( Socket const * sock ) { return setReadFd( sock->get() ); }
694  SelectRead & setReadFd( int fd );
695  SelectRead & delReadFd( int fd );
696  SelectRead & setReadFds( winux::Mixed const & fds );
697  SelectRead & clear();
698  int hasReadSock( Socket const & sock ) const { return hasReadFd( sock.get() ); }
699  int hasReadFd( int fd ) const;
700 
705  int wait( double sec = -1 );
706 protected:
709 };
710 
713 {
714 public:
715  SelectWrite();
716  SelectWrite( Socket const & sock );
717  SelectWrite( Socket const * sock );
718  SelectWrite( int fd );
719  SelectWrite( winux::Mixed const & fds );
720  ~SelectWrite();
721 
722  SelectWrite & setWriteSock( Socket const & sock ) { return setWriteFd( sock.get() ); }
723  SelectWrite & setWriteSock( Socket const * sock ) { return setWriteFd( sock->get() ); }
724  SelectWrite & setWriteFd( int fd );
725  SelectWrite & delWriteFd( int fd );
726  SelectWrite & setWriteFds( winux::Mixed const & fds );
727  SelectWrite & clear();
728  int hasWriteSock( Socket const & sock ) const { return hasWriteFd( sock.get() ); }
729  int hasWriteFd( int fd ) const;
730 
735  int wait( double sec = -1 );
736 protected:
739 };
740 
743 {
744 public:
745  SelectExcept();
746  SelectExcept( Socket const & sock );
747  SelectExcept( Socket const * sock );
748  SelectExcept( int fd );
749  SelectExcept( winux::Mixed const & fds );
750  ~SelectExcept();
751 
752  SelectExcept & setExceptSock( Socket const & sock ) { return setExceptFd( sock.get() ); }
753  SelectExcept & setExceptSock( Socket const * sock ) { return setExceptFd( sock->get() ); }
754  SelectExcept & setExceptFd( int fd );
755  SelectExcept & delExceptFd( int fd );
756  SelectExcept & setExceptFds( winux::Mixed const & fds );
757  SelectExcept & clear();
758  int hasExceptSock( Socket const & sock ) const { return hasExceptFd( sock.get() ); }
759  int hasExceptFd( int fd ) const;
760 
765  int wait( double sec = -1 );
766 protected:
769 };
770 
772 class EIENNET_DLL Select : public SelectRead, public SelectWrite, public SelectExcept
773 {
774 public:
776  Select() { }
777 
778  Select & setReadSock( Socket const & sock ) { SelectRead::setReadSock(sock); return *this; }
779  Select & setReadFd( int fd ) { SelectRead::setReadFd(fd); return *this; }
780  Select & delReadFd( int fd ) { SelectRead::delReadFd(fd); return *this; }
781  Select & setReadFds( winux::Mixed const & fds ) { SelectRead::setReadFds(fds); return *this; }
782  Select & clearReadFds() { SelectRead::clear(); return *this; }
783 
784  Select & setWriteSock( Socket const & sock ) { SelectWrite::setWriteSock(sock); return *this; }
785  Select & setWriteFd( int fd ) { SelectWrite::setWriteFd(fd); return *this; }
786  Select & delWriteFd( int fd ) { SelectWrite::delWriteFd(fd); return *this; }
787  Select & setWriteFds( winux::Mixed const & fds ) { SelectWrite::setWriteFds(fds); return *this; }
788  Select & clearWriteFds() { SelectWrite::clear(); return *this; }
789 
790  Select & setExceptSock( Socket const & sock ) { SelectExcept::setExceptSock(sock); return *this; }
791  Select & setExceptFd( int fd ) { SelectExcept::setExceptFd(fd); return *this; }
792  Select & delExceptFd( int fd ) { SelectExcept::delExceptFd(fd); return *this; }
793  Select & setExceptFds( winux::Mixed const & fds ) { SelectExcept::setExceptFds(fds); return *this; }
794  Select & clearExceptFds() { SelectExcept::clear(); return *this; }
795 
797  Select & clear() { SelectRead::clear(); SelectWrite::clear(); SelectExcept::clear(); return *this; }
798 
803  int wait( double sec = -1 );
804 };
805 
806 } // namespace io
807 
810 {
811 public:
813  clientId(clientId),
814  clientEpStr(clientEpStr),
815  clientSockPtr(clientSockPtr)
816  {
817  }
818 
819  virtual ~ClientCtx()
820  {
821  }
822 
826 
827 private:
829 };
830 
836 template < class _ClientCtxClass >
837 class Server
838 {
839 public:
841  using StartupHandlerFunction = std::function< void( ClientCtxSharedPointer clientCtxPtr ) >;
842 
849  Server( ip::EndPoint const & ep, int threadCount = 4, int backlog = 0, double durationSec = 0.1 ) :
850  _cumulativeClientId(0),
851  _stop(false),
852  _pool( threadCount, winux::ThreadPool::modeWaitTimeRePost, durationSec ),
853  _mtxServer(true)
854  {
855  _stop = !( _servSock.eiennet::Socket::bind(ep) && _servSock.listen(backlog) );
856  }
857 
858  virtual ~Server()
859  {
860  }
861 
862  virtual int run()
863  {
864  while ( !_stop )
865  {
866  io::Select sel;
867  sel.setExceptSock(_servSock);
868  sel.setReadSock(_servSock);
869  int rc = sel.wait(0.5);
870  if ( rc > 0 )
871  {
872  if ( sel.hasReadSock(_servSock) )
873  {
874  ip::EndPoint clientEp;
875  auto clientSockPtr = _servSock.accept(&clientEp);
876  if ( clientSockPtr )
877  {
878  auto & clientCtxPtr = this->_addClient( clientEp, clientSockPtr );
879 
880  // 进入该客户的业务逻辑
881  this->onStartup(clientCtxPtr);
882  }
883  }
884  else if ( sel.hasExceptSock(_servSock) )
885  {
886  _stop = true;
887  }
888  }
889  }
890 
891  _pool.whenEmptyStopAndWait();
892  return 0;
893  }
894 
895  size_t getClientsCount() const
896  {
897  winux::ScopeGuard guard( const_cast<winux::Mutex &>(_mtxServer) );
898  return _clients.size();
899  }
900 
902  {
903  _startupHandler = handler;
904  }
905 
906  void removeClient( winux::uint64 clientId )
907  {
908  winux::ScopeGuard guard(_mtxServer);
909  _clients.erase(clientId);
910  }
911 
912 protected:
914  {
915  ClientCtxSharedPointer * client;
916  {
917  winux::ScopeGuard guard(_mtxServer);
918  ++_cumulativeClientId;
919  client = &_clients[_cumulativeClientId];
920  }
921  client->attachNew( new _ClientCtxClass( _cumulativeClientId, clientEp.toString(), clientSockPtr ) );
922  return *client;
923  }
924 
925  winux::uint64 _cumulativeClientId; // 客户唯一标识
926  bool _stop; // 是否停止
927  winux::ThreadPool _pool; // 线程池
928  winux::Mutex _mtxServer; // 互斥量保护服务器共享数据
929  ip::tcp::Socket _servSock; // 服务器监听套接字
930  std::map< winux::uint64, ClientCtxSharedPointer > _clients; // 客户表
931 
932  // 一个客户的业务逻辑开启
933  virtual void onStartup( ClientCtxSharedPointer clientCtxPtr )
934  {
935  if ( this->_startupHandler ) this->_startupHandler(clientCtxPtr);
936  }
937  StartupHandlerFunction _startupHandler; // onStartup()事件处理
938 
939 private:
941 };
942 
943 } // namespace eiennet
944 
945 
946 
947 #endif // __SOCKET_HPP__
#define EIENNET_FUNC_DECL(ret)
SelectWrite & setWriteSock(Socket const *sock)
int hasExceptSock(Socket const &sock) const
winux::GrowBuffer extraData
SelectRead & setReadSock(Socket const &sock)
Socket(Socket &&other)
移动构造函数
virtual winux::String toString() const
把地址转换成一个字符串
bool bind(winux::String const &ipAddr, winux::ushort port)
Select Write Io模型
SocketStreamIn(SocketStreamBuf *sockBuf)
StartupHandlerFunction _startupHandler
void * getBuf() const
暴露缓冲区指针
Definition: utilities.hpp:485
socket库初始化
bool sendUntilType(_PodType const &v, int msgFlags=MsgDefault)
发送一个Plain of Data类型的变量,若成功返回true,否则返回false。
客户场景类基础
Select & clear()
清空所有fds
SocketStreamOut(winux::SimplePointer< SocketStreamBuf > &sockBuf)
Socket()
构造函数2,新建一个tcp socket.
Select & setExceptFd(int fd)
int wait(double sec=-1)
等待相应的fd就绪。sec<1表示小于1秒的时间,sec<0表示无限等待。eg: sec=1.5表示等待1500ms ...
static int const SdSend
SelectExcept & setExceptSock(Socket const *sock)
winux::ThreadPool _pool
virtual int run()
winux::String const & getHostname() const
获取主机名
Select & setReadSock(Socket const &sock)
Select & setWriteFd(int fd)
std::basic_string< char > AnsiString
Definition: utilities.hpp:165
EndPointArray & getArr()
EndPointArray::const_iterator end() const
static int const MsgDefault
Select Io模型
int get() const
Windows:socket句柄,或Linux:socket描述符
static int const MsgOob
STL namespace.
EndPointArray::iterator begin()
int sendWaitUntil(winux::Buffer const &data, int *hadSent, double sec, int *rcWait, FunctionSuccessCallback eachSuccessCallback=FunctionSuccessCallback(), void *param=nullptr, int msgFlags=MsgDefault)
Socket * getSocket() const
winux::ushort getPort() const
获取端口号
端点基类(套接字地址对象基类)
SocketStreamIn(SocketStreamBuf &sockBuf)
Socket(int sock, bool isNewSock=false)
构造函数1,包装现有socket描述符
Socket()
构造函数2,新建一个udp socket.
int sendTo(winux::String const &ipAddr, winux::ushort port, void const *data, int size, int msgFlags=MsgDefault)
void free()
释放缓冲区
SocketStreamIn(winux::SimplePointer< SocketStreamBuf > &sockBuf)
winux::MembersWrapper< struct Socket_Data > _self
SelectRead & setReadSock(Socket const *sock)
int hasReadSock(Socket const &sock) const
winux::String clientEpStr
#define DISABLE_OBJECT_COPY(clsname)
Definition: utilities.hpp:78
std::map< winux::uint64, ClientCtxSharedPointer > _clients
Select & setWriteSock(Socket const &sock)
Select & delWriteFd(int fd)
static int const MsgDontRoute
Select & delExceptFd(int fd)
互斥量
Definition: threads.hpp:256
winux::SharedPointer< Socket > accept(EndPoint *ep=NULL)
接受一个客户连接
void onStartupHandler(StartupHandlerFunction handler)
SocketStreamIn(winux::SharedPointer< SocketStreamBuf > &sockBuf)
void removeClient(winux::uint64 clientId)
Server(ip::EndPoint const &ep, int threadCount=4, int backlog=0, double durationSec=0.1)
构造函数1
Select Read Io模型
Select & setReadFds(winux::Mixed const &fds)
Select & setExceptSock(Socket const &sock)
int ConnectAttempt(Socket *sock, Resolver const &resolver, winux::uint32 perCnnTimeoutMs)
阻塞模式Socket连接尝试,连接成功返回0,超时返回1,失败返回-1
int send(winux::Buffer const &data, int msgFlags=MsgDefault)
发送数据
static int const SdBoth
void attachNew(_Ty *p)
Definition: smartptr.hpp:682
作用域范围保护
Definition: system.hpp:174
ip::tcp::Socket _servSock
winux::SharedPointer< Socket > accept(EndPoint *ep=NULL)
接受一个客户连接
uint getSize() const
获取数据大小
Definition: utilities.hpp:494
Socket(Socket &&other)
移动构造函数
套接字基类
Select & setReadFd(int fd)
缓冲区,表示内存中一块2进制数据(利用malloc/realloc进行内存分配)
Definition: utilities.hpp:436
#define EIENNET_DLL
数据收发场景,存放数据收发过程中的一些变量
Socket(int sock, bool isNewSock=false)
构造函数1,包装现有socket描述符
std::function< void(ClientCtxSharedPointer clientCtxPtr) > StartupHandlerFunction
winux::MembersWrapper< struct SelectRead_Data > _self
EndPointArray::iterator end()
套接字错误
ClientCtxSharedPointer & _addClient(ip::EndPoint const &clientEp, winux::SharedPointer< ip::tcp::Socket > clientSockPtr)
static int const MsgPartial
unsigned int uint
Definition: utilities.hpp:128
SelectExcept & setExceptSock(Socket const &sock)
int hasWriteSock(Socket const &sock) const
Select & setWriteFds(winux::Mixed const &fds)
服务器类基础
线程池,创建一组线程等待着从任务队列中获取任务执行
Definition: threads.hpp:619
SocketStreamOut(winux::SharedPointer< SocketStreamBuf > &sockBuf)
static int const MsgWaitAll
Select & delReadFd(int fd)
bool sendUntil(winux::Buffer const &data, int msgFlags=MsgDefault)
网络通信库
高效的可增长缓冲区,1.33倍冗余量
Definition: utilities.hpp:531
static int const MsgInterrupt
bool recvUntilType(_PodType *v, int msgFlags=MsgDefault)
接收一个Plain of Data类型的变量,若成功返回true,否则返回false。
SocketError(int errType, winux::AnsiString const &errStr)
void setBuf(void *buf, uint size, uint capacity, bool isPeek)
设置缓冲区,当isPeek为false时拷贝数据缓冲区
ClientCtx(winux::uint64 clientId, winux::String clientEpStr, winux::SharedPointer< ip::tcp::Socket > clientSockPtr)
主机名解析器(可以把域名解析为一个或多个IP端点)
std::vector< ip::EndPoint > EndPointArray
unsigned short ushort
Definition: utilities.hpp:131
混合体,能表示多种类型的值
Definition: utilities.hpp:586
winux::MembersWrapper< struct SelectExcept_Data > _self
int send(winux::AnsiString const &data, int msgFlags=MsgDefault)
发送数据
简单指针
Definition: smartptr.hpp:232
winux::uint64 _cumulativeClientId
static int const MsgMaxIovLen
错误类
Definition: utilities.hpp:413
EndPointArray::const_iterator begin() const
Select()
Select模型构造函数
static int const SdReceive
unsigned long long uint64
Definition: utilities.hpp:146
size_t getClientsCount() const
SelectWrite & setWriteSock(Socket const &sock)
bool connect(winux::String const &ipAddr, winux::ushort port)
unsigned int uint32
Definition: utilities.hpp:128
bool sendUntil(winux::AnsiString const &data, int msgFlags=MsgDefault)
SocketStreamOut(SocketStreamBuf &sockBuf)
winux::Mutex _mtxServer
winux::SharedPointer< ip::tcp::Socket > clientSockPtr
std::function< void(int hadBytes, void *param) > FunctionSuccessCallback
int sendWaitUntil(winux::AnsiString const &data, int *hadSent, double sec, int *rcWait, FunctionSuccessCallback eachSuccessCallback=FunctionSuccessCallback(), void *param=nullptr, int msgFlags=MsgDefault)
SocketStreamOut(SocketStreamBuf *sockBuf)
int count() const
获取解析到的IP端点数
winux::uint64 clientId
std::basic_string< tchar > String
Definition: utilities.hpp:162
virtual void onStartup(ClientCtxSharedPointer clientCtxPtr)
static int const MsgPeek
EndPointArray const & getArr() const
Select & setExceptFds(winux::Mixed const &fds)
跨平台基础功能库
Definition: archives.hpp:7
Select Except Io模型
winux::MembersWrapper< struct SelectWrite_Data > _self