Socket mode-non-blocking mode development (4) -- Server

Source: Internet
Author: User

There are only four hundred lines of server code, mainly acceptthread and helperthread thread. The Code is as follows:

// Server. CPP: defines the entry point for the console application. <br/> // </P> <p> # include "stdafx. H "<br/> # include <iostream. h> <br/> # include <afx. h> <br/> # include <WINBASE. h> <br/> # include <winsock2.h> <br/> # include <process. h> <br/> # include <list> <br/> # include "client. H "</P> <p>/* <br/> * the first letter of the variable is lowercase, and the letter indicates the type of the variable, such as nerrcode. error code that is an integer <br/> * the first letter of the function is capitalized and indicates the function. For example, void acceptthread (void ). the thread that accepts the connection <br/> */<br/> # pragma comment (Lib, "ws2_32.lib") </P> <p> using namespace STD; <br/> typedef list <cclient *> clientlist; // linked list </P> <p> # define serverport5556 // server TCP port <br/> # define server_setup_fail1 // server startup failure </P> <p> # define timefor_thread_exit5000 // sleep time of the main thread <br/> # define timefor_thread_help1500 // The Exit Time of the cleanup resource thread <br/> # define timefor_thread_sleep500 // wait for the sleep time of the client request thread </P> <p> handlehthread Accept; // accept the client connection thread handle <br/> handlehthreadhelp; // release the resource thread handle <br/> socketsserver; // listener socket <br/> boolbserverrunning; // The server's working status <br/> handlehserverevent; // closes the server event object <br/> clientlistclientlist; // manages the connected linked list <br/> critical_sectioncsclientlist; // protect the critical area object of the linked list </P> <p> boolinitsever (void); // initialization <br/> boolstartservice (void ); // start the service <br/> voidstopservice (void); // stop the service <br/> boolcreatehelperandacceptthread (void); // create a connection thread for the receiving client <br/> V Oidexitserver (void); // server logout </P> <p> voidinitmember (void); // initialize the global variable <br/> boolinitsocket (void ); // initialize socket </P> <p> voidshowtipmsg (bool bfirstinput); // display the prompt message <br/> voidshowserverstartmsg (bool bsuc ); // display that the server has been started <br/> voidshowserverexitmsg (void); // display that the server is exiting </P> <p> DWORD _ stdcallhelperthread (void * pparam ); // release resources <br/> DWORD _ stdcall acceptthread (void * pparam); // accept the client connection thread <br/> voidshowconnectnum (); // display the number of client connections </ P> <p> int main (INT argc, char * argv []) <br/>{< br/> // initialize the server <br/> If (! Initsever () <br/>{< br/> exitserver (); <br/> return server_setup_fail; <br/>}</P> <p> // start the service <br/> If (! Startservice () <br/>{< br/> showserverstartmsg (false); <br/> exitserver (); <br/> return server_setup_fail; <br/>}</P> <p> // stop the service <br/> stopservice (); </P> <p> // server logout <br/> exitserver (); </P> <p> return 0; <br/>}</P> <p>/** <br/> * initialization <br/> */<br/> boolinitsever (void) <br/>{</P> <p> initmember (); // initialize the global variable </P> <p> // initialize the socket <br/> If (! Initsocket () <br/> return false; </P> <p> return true; <br/>}</P> <p>/** <br/> * initialize the global variable <br/> */<br/> voidinitmember (void) <br/>{< br/> initializecriticalsection (& csclientlist); // initialize the critical section <br/> hserverevent = createevent (null, true, false, null ); // manually set the event and initialize it to the State without an information number <br/> hthreadaccept = NULL; // set it to null <br/> hthreadhelp = NULL; // set to null <br/> sserver = invalid_socket; // set to invalid socket <br/> bserverrunning = false ;// The server is not running <br/> clientlist. clear (); // clear the linked list <br/>}</P> <p>/** <br/> * initialize socket <br/> */<br/> bool initsocket (void) <br/>{< br/> // return value <br/> int reval; </P> <p> // initialize Windows Sockets DLL <br/> wsadata wsdata; <br/> reval = wsastartup (makeword (2, 2), & wsdata); </P> <p> // create a socket <br/> sserver = socket (af_inet, sock_stream, 0); <br/> If (invalid_socket = sserver) <br/> return false; </P> <p> // set the socket non-blocking mode <br/> unsigned long Ul = 1; <br/> reval = ioctlsocket (sserver, fionbio, (unsigned long *) & UL); <br/> If (socket_error = reval) <br/> return false; </P> <p> // bind a socket <br/> sockaddr_in seraddr; <br/> seraddr. sin_family = af_inet; <br/> seraddr. sin_port = htons (SERVERPORT); <br/> seraddr. sin_addr.s_un.s_addr = inaddr_any; <br/> reval = BIND (sserver, (struct sockaddr *) & seraddr, sizeof (seraddr); <br/> If (socket_error = reval) <br/> Return false; </P> <p> // listener <br/> reval = listen (sserver, somaxconn); <br/> If (socket_error = reval) <br/> return false; </P> <p> return true; <br/>}</P> <p>/** <br/> * start the service <br/> */<br/> boolstartservice (void) <br/>{< br/> bool reval = true; // return value </P> <p> showtipmsg (true ); // prompt the user to enter </P> <p> char cinput; // enter the character <br/> DO <br/>{< br/> CIN> cinput; <br/> If ('s '= cinput |'s' = cinput) <br/>{< br/> If (createhelpera Ndacceptthread () // create a thread to clear resources and accept client requests <br/>{< br/> showserverstartmsg (true ); // information about successful thread creation <br/>}else {<br/> reval = false; <br/>}< br/> break; // jump out of the loop body </P> <p >}else {<br/> showtipmsg (true ); <br/>}</P> <p>} while (cinput! = 'S' & // The character 's' or 'S' must be entered. <br/> cinput! ='S '); </P> <p> return reval; <br/>}</P> <p>/** <br/> * stop the service <br/> */<br/> voidstopservice (void) <br/>{< br/> bool reval = true; // return value </P> <p> showtipmsg (false ); // prompt the user to enter </P> <p> char cinput; // The input operation character <br/> for (; bserverrunning ;) <br/>{< br/> CIN> cinput; <br/> If (cinput = 'E' | cinput = 'E ') <br/>{< br/> If (idok = MessageBox (null, "Are you sure? ", // Message box waiting for user confirmation to exit <br/>" server ", mb_okcancel) <br/>{< br/> break; // jump out of the loop body <br/>} else {<br/> sleep (timefor_thread_exit ); // thread sleep <br/>}< br/>} else {<br/> sleep (timefor_thread_exit ); // thread sleep <br/>}</P> <p> bserverrunning = false; // server logout </P> <p> showserverexitmsg (); // Display Server exit Information </P> <p> sleep (timefor_thread_exit); // give other threads time to exit </P> <p> waitforsingleobject (hserverevent, infinite ); // events waiting for the resource to be cleared </P> <p> return; <br/>} </P> <p>/** <br/> * display prompt information <br/> */<br/> voidshowtipmsg (bool bfirstinput) <br/>{< br/> If (bfirstinput) // The first time <br/>{< br/> cout <Endl; <br/> cout <Endl; <br/> cout <"**********************" <Endl; <br/> cout <"**" <Endl; <br/> cout <"* s (s): Start server *" <Endl; <br/> cout <"**" <Endl; <br/> cout <"**********************" <Endl; <br/> cout <"Please input:" <Endl; </P> <p >}else {// Exit the server <br/> cout <Endl; <br/> cout <"**********************" <Endl; <br/> cout <"**" <Endl; <br/> cout <"* E (e): Exit server *" <Endl; <br/> cout <"**" <Endl; <br/> cout <"**********************" <Endl; <br/> cout <"Please input:" <Endl; <br/>}< br/>/** <br/> * release resources <br/> */<br/> void exitserver (void) <br/>{< br/> deletecriticalsection (& csclientlist ); // Release the critical zone object <br/> closehandle (hserverevent); // release the event object handle <br/> closesocket (sserver ); // disable socket <br/> wsacleanup (); // uninstall Windows Sockets DLL <br/>}</P> <p>/** <br/> * create a resource release thread and a client request receiving thread <br/> * /<br/> bool createhelperandacceptthread (void) <br/>{</P> <p> bserverrunning = true; // set the server to running status </P> <p> // create a resource release thread <br/> unsigned long ulthreadid; <br/> hthreadhelp = createthread (null, 0, helperthread, null, 0, & ulthreadi D); <br/> If (null = hthreadhelp) <br/>{< br/> bserverrunning = false; <br/> return false; <br/>} else {<br/> closehandle (hthreadhelp ); <br/>}</P> <p> // create a receiving client request thread <br/> hthreadaccept = createthread (null, 0, acceptthread, null, 0, & ulthreadid); <br/> If (null = hthreadaccept) <br/>{< br/> bserverrunning = false; <br/> return false; <br/>} else {<br/> closehandle (hthreadaccept); <br/>}</P> <p> return true; <br />}</P> <p>/** <br/> * message indicating the server startup Success and Failure <br/> */<br/> void showserverstartmsg (bool bsuc) <br/>{< br/> If (bsuc) <br/> {<br/> cout <"************************" <Endl; <br/> cout <"**" <Endl; <br/> cout <"* server succeeded! * "<Endl; <br/> cout <" ** "<Endl; <br/> cout <"**********************" <Endl; <br/>} else {<br/> cout <"***********************" <endl; <br/> cout <"**" <Endl; <br/> cout <"* server failed! * "<Endl; <br/> cout <" ** "<Endl; <br/> cout <"**********************" <Endl; <br/>}</P> <p>/** <br/> * display the server logout message <br/> */<br /> void showserverexitmsg (void) <br/> {</P> <p> cout <"**********************" <<Endl; <br/> cout <"**" <Endl; <br/> cout <"* server exit... * "<Endl; <br/> cout <" ** "<Endl; <br/> cout <"**********************" <Endl; <br/>}</P> <p>/** <br/> * Connect to the client <br/> */<br/> DWORD _ stdcall acceptthread (void * pparam) <br/>{< br/> socket saccept; // accept the Socket connected by the client <br/> sockaddr_in addrclient; // The socket address of the client </P> <p> for (; bserverrunning ;) // server status <br/>{< br/> memset (& addrclient, 0, sizeof (sockaddr_in )); // initialization <br/> intlenclient = sizeof (sockaddr_in); // address length <br/> saccept = accept (sserver, (sockaddr *) & addrclient, & lenclient ); // accept customer requests </P> <p> If (invalid_socket = SACC EPT) <br/>{< br/> int nerrcode = wsagetlasterror (); <br/> If (nerrcode = wsaewouldblock) // an unblocking socket operation cannot be completed immediately <br/>{< br/> sleep (timefor_thread_sleep); <br/> continue; // continue waiting <br/>} else {<br/> return 0; // exit by thread <br/>}</P> <p >}< br/> else // receives client requests <br/>{< br/> cclient * pclient = new cclient (saccept, addrclient); // create a client object <br/> entercriticalsection (& csclientlist); // enter the clientlist in the critical section <br/>. push_back (pclient); // Add Linked List <br/> leavecriticalsection (& csclientlist); // exit the critical section </P> <p> pclient-> startruning (); // set up a receiving data and sending data thread for the accepted client <br/>}</P> <p> return 0; // exit the thread <br/>}</P> <p>/** <br/> * clear resources <br/> */<br/> DWORD _ stdcall helperthread (void * pparam) <br/>{< br/> for (; bserverrunning;) // the server is running <br/>{< br/> entercriticalsection (& csclientlist ); // enter the critical section </P> <p> // clear the memory space of the disconnected client. <br/> clientlist: iterator iter = clientlist. begi N (); <br/> for (ITER; iter! = Clientlist. end ();) <br/>{< br/> cclient * pclient = (cclient *) * ITER; <br/> If (pclient-> isexit ()) // The client thread has exited <br/>{< br/> clientlist. erase (ITER ++); // delete a node <br/> Delete pclient; // release the memory <br/> pclient = NULL; <br/>} else {<br/> ITER ++; // move the pointer down <br/>}</P> <p> leavecriticalsection (& csclientlist ); // leave the critical section </P> <p> sleep (timefor_thread_help); <br/>}</P> <p> // The server stops working <br/> If (! Bserverrunning) <br/>{< br/> // disconnect each connection and the thread exits <br/> entercriticalsection (& csclientlist); <br/> clientlist :: iterator iter = clientlist. begin (); <br/> for (ITER; iter! = Clientlist. end ();) <br/>{< br/> cclient * pclient = (cclient *) * ITER; <br/> // if the client connection still exists, disconnect and the thread exits. <br/> If (pclient-> isconning () <br/>{< br/> pclient-> disconning (); <br/>}< br/> + ITER; <br/>}< br/> // exit the critical section <br/> leavecriticalsection (& csclientlist ); </P> <p> // specify the thread time for the client to automatically exit. <br/> sleep (timefor_thread_sleep ); </P> <p> // enter the critical section <br/> entercriticalsection (& csclientlist ); </P> <p> // make sure that the memory space allocated to each client is recycled. <Br/> // if you do not add the while loop, this may happen. When pclient-> isexit (), the thread has not exited. <Br/> // you need to re-judge from the beginning of the linked list. <Br/> while (0! = Clientlist. Size () <br/>{< br/> iter = clientlist. Begin (); <br/> for (ITER; iter! = Clientlist. end ();) <br/>{< br/> cclient * pclient = (cclient *) * ITER; <br/> If (pclient-> isexit ()) // The client thread has exited <br/>{< br/> clientlist. erase (ITER ++); // delete a node <br/> Delete pclient; // release memory space <br/> pclient = NULL; <br/>} else {<br/> ITER ++; // move the pointer down <br/>}< br/> // set the thread time for the client to automatically exit <br/> sleep (timefor_thread_sleep ); <br/>}< br/> leavecriticalsection (& csclientlist); // exit the critical section </P> <p >}</P> <p> clientlist. clear (); // clear the linked list </P> <p> setevent (hserverevent); // notify the main thread to exit </P> <p> return 0; <br/>}

 

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.