The previous one wrote how to compile Ace, the technical difficulty is difficult. Today we will take a frame. The most efficient IO model on the Win32 platform is not completed. The 9CBS is about completing the port. There is a very good package for the completion of the Win32 platform in ACE. The Win32 implementation of the previous frame in the ACE is the completion of the port. Let's first take a look at which components of this framework. ACE_Proactor forwarder, true name. How good is the asynchronous event distributor. ACE_SERVICE_HANDLER Event Processor. Handle all asynchronous operations. ACE_ASYNCH_ACCEPT Asynchronous Connect Receiver. Used to monitor connection requests from customers. ACE_ASYNCH_READ_STREAM Asynchronous Reader. Start a request for asynchronous reading. ACE_ASYNCH_WRITE_STREAM asynchronous writer. Start a request for asynchronous write operations. Ok! Things are almost aligned. Don't see something above, it is actually very simple, please believe me. Let's first talk about the process of running. First, we will use the Open () method of Accept, and listen to a port. ACE_INET_ADDR localhost; localhost.set (8888, "127.0.0.1"); Acceptor.Open (localhost); At this time, when there is a client's connection request arrives, the front-cutler will automatically call acceptor's Make_Handle () method, come Create an event proceed to process the user of this connection. // I defined the user event processor class, inherited to ace_service_handler cTG_GS_USER_HANDLER * PUSER_HANDLER; // Using ACE creation macro, assign a space. ACE_NEW_NORETURN (Puser_Handler, CTG_GS_USER_HANDLER (this));
IF (Puser_Handler == NULL) {std :: cout << "The system is wrong when the user assigns space, the user does not log in normally"; return 0;} return PUSER_HANDLER; the front-camera is obtained by calling this method, get Puser_Handler The handle and set the socket with this handle. Subsequent, the front-shifter will follow the open method of calling CTG_GS_USER_HANDLER. The prototype of the method is as follows:
Void Ace_Service_Handler :: Open (ACE_HANDLE NEW_HANDLE, ACE_MESSAGE_BLOCK & Message_block)
This is a virtual method for ACE_SERVICE_HANDLER, which requires us to inherit to complete some of our initialization preparations.
The CTG_GS_USER_HANDLER class we defined above is a very important part that handles most of the IO events. He inherited the ACE_SERVICE_HANDLER to achieve three methods below.
Virtual void handle_time_out (const ace_time_value & TV, const void * p);
Timer callback function
Virtual Void Handle_read_Stream (const ace_asynch_read_stream :: result& ";
Read operation callback function
Virtual void Handle_Write_Stream (const ace_asynch_write_stream :: result ";
Write operation callback function
For example, when we initiate an asynchronous read operation.
// reader_ is an asynchronous reader mentioned above
Reader_.read (* MBLK_, SIZEOF (CCMDMESSAGEHEAD)); When the read operation is completed, or when the part is completed, it will call the Handle_Read_Stream method.
We have to do the following processing.
Void CTG_GS_USER_HANDLER :: Handle_Read_Stream (const a_asynch_read_stream :: result&ros)
{
/ / Update the last reception time
IF (! Result.success () || Result.bytes_Transferred () == 0)
{
// If the transmission is unsuccessful, or return to 0 bytes. The customer is also handled here when disconnecting.
Return;
}
Else IF (Result.bytes_Transferred () // If there is no reception, continue to receive. Reader_.read (* MBLK_, Result.bytes_to_read () - Result.bytes_TransferRed ()); Else IF (MBLK _-> length () == sizeof (ccmdMessagehead) { // The receiver is completed, and the message body is expanded. CCMDMESSAGEHEAD * PMSGHEAD; PMSGHEAD = (ccmdMessagehead *) MBLK _-> rd_ptr (); PMSGHEAD-> ULSID = this-> m_usersid; // If there is no additional information, it is submitted directly. IF (PMSGHEAD-> Ulmsglength == 0) { IF (aly_thread_pool :: instance () -> PUTQ (MBLK_) == -1) { MBLK _-> release (); Return; } ACE_NEW_NORTURN (MBLK_, ACE_MESSAGE_BLOCK (ACE_DEFAULT_CDR_BUFSIZE)); ACE_CDR :: MB_ALIGN (MBLK_); Reader_.read (* MBLK_, SIZEOF (CCMDMESSAGEHEAD); } Else { MBLK _-> size (pmsghead-> ulmsglength sizeof (ccmdMessagehead); // put a new message head with the message body. Reader_.read (* MBLK_, PMSGHEAD-> Ulmsglength); } } Else { // Complete reception message is placed in the reception message list of the receiving thread pool. IF (aly_thread_pool :: instance () -> PUTQ (MBLK_) == -1) { MBLK _-> release (); Return; } ACE_NEW_NORTURN (MBLK_, ACE_MESSAGE_BLOCK (ACE_DEFAULT_CDR_BUFSIZE)); ACE_CDR :: MB_ALIGN (MBLK_); Reader_.read (* MBLK_, SIZEOF (CCMDMESSAGEHEAD); } Return; } This way, we have received a message completely. This may not understand some types and variables, I will slowly tell you later, and I will come back immediately.