A reactor model based on select multi-channel splitter in Windows

Source: Internet
Author: User

1. it encapsulates the synchronization variables in windows, including the implementation of condition and monitor. I wanted to encapsulate the thread and want to encapsulate the variables similar to boost: bind or signal/solt. I gave up.

2. this reactor model does not rule out the delivery of multiple eventhandler on the same socket. an eventhandler processes only one socket event (readable and writable. of course, the event can be masked. This is not used in this example .)

3. Use vs2005 for compilation. The project carries a test server and a client that only sends data, and a client that sends and receives data at the same time.

 

4. Code excerpt:

 

Eventhandler

Class sceventhandler <br/>{< br/> Public: <br/> sceventhandler (void); <br/> virtual ~ Sceventhandler (void); </P> <p> virtual int handler_read () {return 1 ;}< br/> virtual int handler_write () {return 1 ;} <br/> virtual int handler_expet () {return 1 ;}< br/> virtual void handler_closed () {Delete this ;}< br/> }; </P> <p> Enum handlertype <br/> {<br/> handle_connect, <br/> handle_accept, <br/> handle_write, <br/> handle_read, <br/> handle_expt <br/>}; </P> <p> class scsockethandler: Public sceventhandler <br/>{< br/> public: <br/> scsockethandler () {}; <br/> scsockethandler (scsocket S, handlertype E); <br/> void setsocket (scsocket S, handlertype E) {m_sk = s; m_e = e ;}< br/> scsocket getsocket (); <br/> handlertype GetType (); </P> <p> protected: <br/> scsocket m_sk; <br/> handlertype m_e; <br/> };

 

Synchronization variable:

Class mysyncobject <br/>{< br/> Public: <br/> mysyncobject (void); <br/> virtual ~ Mysyncobject (void); <br/> virtual bool lock (DWORD time = infinite); <br/> virtual bool unlock () = 0; <br/> virtual bool unlock (Long Count, long * precount = NULL) {return true ;}< br/> operator handle () {return m_handle ;} <br/> protected: <br/> handle m_handle; <br/>}; </P> <p> class mymutex: public mysyncobject <br/>{< br/> Public: <br/> mymutex (lpsecurity_attributes LPAs = NULL, bool bowner = true, lpctstr Nam E = NULL) <br/>{< br/> m_handle =: createmutex (LPAs, bowner, name); <br/>}< br/> bool unlock () <br/>{< br/> return: releasemutex (m_handle); <br/>}</P> <p> virtual ~ Mymutex () <br/>{< br/>}< br/>}; </P> <p> class mysemphore: public mysyncobject <br/>{< br/> Public: <br/> mysemphore (long lineconds = 1, long Lmax = 1, lpsecurity_attributes LPAs = NULL, lpctstr name = NULL) <br/>{< br/> m_handle =: createsemaphore (LPAs, linmtr, Lmax, name); <br/>}< br/> bool unlock () <br/>{< br/> return unlock (1); <br/>}< br/> bool unlock (Long Count, long * precount = NULL) <br/>{< br/> return: releasesemaphore (m_handle, Count, precount); <br/>}< br/> }; </P> <p> class mycondition <br/> {<br/> Public: <br/> mycondition (): m_semhpore (0, 1), m_count (0) {}< br/> void wait (mymutex & mutex, DWORD time = infinite); <br/> void noticeone (); <br/> void NOTICEAll (); <br/> PRIVATE: <br/> mysemphore m_semhpore; <br/> long m_count; <br/>}; </P> <p> class mymonitor: public mysyncobject <br/>{< br/> Public: <br/> mymonitor (): m_mutex (null, false) {}< br/> bool lock (DWORD time = infinite); <br/> bool unlock (); <br/> void wait (DWORD time = infinite ); <br/> void noticeone (); <br/> void NOTICEAll (); <br/> PRIVATE: <br/> mymutex m_mutex; <br/> mycondition m_condition; <br/> };

 

Reactor main execution function:

Void screactor: Run () <br/> {<br/> // There is no listen or connect blocking here <br/> If (m_fdread.fd_count = 0 & m_fdwrite.fd_count = 0 & m_fdexept.fd_count = 0) <br/>{< br/> m_mutex.lock (); <br/> m_condition.wait (m_mutex); <br/> m_mutex.unlock (); <br/>}< br/> while (true) <br/>{< br/> fd_set fd_read, fd_write, fd_exept; <br/> memcpy (& fd_read, & m_fdread, sizeof (m_fdread); <br/> memcpy (& fd_write, & m_fdwrite, sizeof (m_fdwrite); <br /> Memcpy (& fd_exept, & m_fdexept, sizeof (m_fdexept); <br/> int ret = select (0, & fd_read, & fd_write, & fd_exept, null ); <br/> If (ret = socket_error) <br/>{</P> <p >}< br/> else if (Ret> 0) <br/>{< br/> m_mutex.lock (); <br/> while (Ret --> 0) <br/> {<br/> // a socket can contain both readable and writable data. <br/> // Note: Each socket corresponds to multiple handler, handler calls that should not be processed, but the handler that should be called is not called. <br/> // NOTE 2: If the handler's handler function has a register or removehandler operation, the iterator Auto-increment operation problems <br/> for (STD: Set <scsockethandler *>: iterator it = m_handlers.begin (); it! = M_handlers.end (); ++ it) <br/>{< br/> scsockethandler * Handler = * it; <br/> int result = 0; <br/> bool bprocess = false; <br/> handlertype E = Handler-> GetType (); <br/> If (fd_isset (Handler-> getsocket (), & fd_read) <br/>{< br/> If (E = handle_accept | E = handle_read) <br/>{< br/> result = Handler-> handler_read (); <br/> bprocess = true; <br/> fd_clr (Handler-> getsocket (), & fd_read); <br/>}< br/> else If (fd_isset (Handler-> getsocket (), & fd_write) <br/>{< br/> If (E = handle_connect | E = handle_write) <br/>{< br/> result = Handler-> handler_write (); <br/> bprocess = true; <br/> fd_clr (Handler-> getsocket (), & fd_write); <br/>}< br/> else if (fd_isset (Handler-> getsocket (), & fd_exept )) <br/>{< br/> result = Handler-> handler_expet (); <br/> bprocess = true; <br/> fd_clr (Handler-> getsocket (), & fd_exe Pt); <br/>}< br/> If (bprocess) <br/>{< br/> If (result <0) <br/> {<br/> If (result =-2) <br/> {<br/> //-2 is defined as socket disabling, clear related handler <br/> scsocket earsesocket = Handler-> getsocket (); <br/> for (STD: Set <scsockethandler *> :: iterator it = m_handlers.begin (); it! = M_handlers.end ();) <br/>{< br/> scsockethandler * earsehandler = * it; <br/> If (earsehandler-> getsocket () = earsesocket) <br/>{< br/> removehandler (earsehandler); <br/> it = m_handlers.begin (); <br/> earsehandler-> handler_closed (); <br/>}< br/> else <br/> {<br/> + + it; <br/>}</P> <p >}< br/> else <br/>{< br/> removehandler (handler ); <br/>}< br/> break; <br/>}< br/> m_mutex.unlock (); <br/>}< br/>}

 

Test server code:

Void main (INT argc, char ** argv) <br/>{< br/> socketguard; <br/> screactor reactor; <br/> cserverappector server (& reactor); <br/> server. open (scsocketaddress ("127.0.0.1", 7000), & reactor); <br/> while (true) <br/>{< br/> sleep (100000 ); <br/>}< br/>}

 

Complete project example download link: http://download.csdn.net/source/2938873

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.