⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 talker.cpp

📁 ace开发环境 用来开发网络程序 其运用了设计模式、多平台、C++等多种知识
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// $Id: Talker.cpp 78962 2007-07-20 03:27:14Z sowayaa $// ============================================================================//// = LIBRARY//    examples//// = FILENAME//    Talker.cpp//// = DESCRIPTION////    This test application tests a wide range of events that can be//    demultiplexed using various ACE utilities.  Events used include//    ^C events, reading from STDIN, vanilla Win32 events, thread//    exits, Reactor notifications, proactive reads, and proactive//    writes.////    The proactive I/O events are demultiplexed by the ACE_Proactor.//    The thread exits, notications, and vanilla Win32 events are//    demultiplexed by the ACE_Reactor.  To enable a single thread//    to run all these events, the Proactor is integrated with the//    Reactor.////    The test application prototypes a simple talk program.  Two//    instances of the application connect.  Input from either console//    is displayed on the others console also.  Because of the evils//    of Win32 STDIN, a separate thread is used to read from STDIN.//    To test the Proactor and Reactor, I/O between the remote//    processes is performed proactively and interactions between the//    STDIN thread and the main thread are performed reactively.////    The following description of the test application is in two//    parts.  The participants section explains the main components//    involved in the application.  The collaboration section//    describes how the partipants interact in response to the//    multiple event types which occur.////    The Reactor test application has the following participants:////    . Reactor -- The Reactor demultiplexes Win32 "waitable"//    events using WaitForMultipleObjects.////    . Proactor -- The proactor initiates and demultiplexes//    overlapped I/O operations.  The Proactor registers with the//    Reactor so that a single-thread can demultiplex all//    application events.////    . STDIN_Handler -- STDIN_Handler is an Active Object which reads//    from STDIN and forwards the input to the Peer_Handler.  This//    runs in a separate thread to make the test more interesting.//    However, STDIN is "waitable", so in general it can be waited on//    by the ACE Reactor, thanks MicroSlush!////    . Peer_Handler -- The Peer_Handler connects to another instance//    of test_reactor.  It Proactively reads and writes data to the//    peer.  When the STDIN_Handler gives it messages, it fowards them//    to the remote peer.  When it receives messages from the remote//    peer, it prints the output to the console.////    The collaborations of the participants are as follows:////    . Initialization////      Peer_Handler -- connects to the remote peer.  It then begins//      proactively reading from the remote connection.  Note that it//      will be notified by the Proactor when a read completes.  It//      also registers a notification strategy with message queue so//      that it is notified when the STDIN_Handler posts a message//      onto the queue.////      STDIN_Handler -- STDIN_Handler registers a signal handler for//      SIGINT.  This just captures the exception so that the kernel//      doesn't kill our process; We want to exit gracefully.  It also//      creates an Exit_Hook object which registers the//      STDIN_Handler's thread handle with the Reactor.  The//      Exit_Hook will get called back when the STDIN_Handler thread//      exits.  After registering these, it blocks reading from STDIN.////      Proactor -- is registered with the Reactor.////      The main thread of control waits in the Reactor.////    . STDIN events -- When the STDIN_Handler thread reads from//    STDIN, it puts the message on Peer_Handler's message queue.  It//    then returns to reading from STDIN.////    . Message enqueue -- The Reactor thread wakes up and calls//    Peer_Handler::handle_output.  The Peer_Handler then tries to//    dequeue a message from its message queue.  If it can, the//    message is Proactively sent to the remote peer.  Note that the//    Peer_Handler will be notified with this operation is complete.//    The Peer_Handler then falls back into the Reactor event loop.////    . Send complete event -- When a proactive send is complete, the//    Proactor is notified by the Reactor.  The Proactor, in turn,//    notifies the Peer_Handler.  The Peer_Handler then checks for//    more messages from the message queue.  If there are any, it//    tries to send them.  If there are not, it returns to the//    Reactor event loop.////    . Read complete event -- When a proactive read is complete (the//    Peer_Handler initiated a proactive read when it connected to the//    remote peer), the Proactor is notified by the Reactor.  The//    Proactor, in turn notifies the Peer_Handler.  If the read was//    successful the Peer_Handler just displays the received msg to//    the console and reinvokes a proactive read from the network//    connection.  If the read failed (i.e. the remote peer exited),//    the Peer_Handler sets a flag to end the event loop and returns.//    This will cause the application to exit.////    . ^C events -- When the user types ^C at the console, the//    STDIN_Handler's signal handler will be called.  It does nothing,//    but as a result of the signal, the STDIN_Handler thread will//    exit.////    . STDIN_Handler thread exits -- The Exit_Hook will get called//    back from the Reactor.  Exit_Hook::handle_signal sets a flag//    to end the event loop and returns.  This will cause the//    application to exit.//////    To run example, start an instance of the test with an optional//    local port argument (as the acceptor). Start the other instance//    with -h <hostname> and -p <server port>. Type in either the//    client or server windows and your message should show up in the//    other window.  Control C to exit.//// = AUTHOR//    Tim Harrison//    Irfan Pyarali//// ============================================================================#include "ace/OS_main.h"#if defined (ACE_HAS_WIN32_OVERLAPPED_IO)#include "ace/Reactor.h"#include "ace/Reactor_Notification_Strategy.h"#include "ace/WIN32_Proactor.h"#include "ace/Proactor.h"#include "ace/SOCK_Connector.h"#include "ace/SOCK_Acceptor.h"#include "ace/Get_Opt.h"#include "ace/Service_Config.h"#include "ace/Task.h"#include "ace/OS_NS_unistd.h"ACE_RCSID(WFMO_Reactor, Talker, "$Id: Talker.cpp 78962 2007-07-20 03:27:14Z sowayaa $")typedef ACE_Task<ACE_MT_SYNCH> MT_TASK;class Peer_Handler : public MT_TASK, public ACE_Handler// = TITLE//     Connect to a server.  Receive messages from STDIN_Handler//     and forward them to the server using proactive I/O.{public:  // = Initialization methods.  Peer_Handler (int argc, ACE_TCHAR *argv[]);  ~Peer_Handler (void);  //FUZZ: disable check_for_lack_ACE_OS  int open (void * =0);  // This method creates the network connection to the remote peer.  // It does blocking connects and accepts depending on whether a  // hostname was specified from the command line.  //FUZZ: enable check_for_lack_ACE_OS  virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result);  // This method will be called when an asynchronous read completes on a stream.  // The remote peer has sent us something.  If it succeeded, print  // out the message and reinitiate a read.  Otherwise, fail.  In both  // cases, delete the message sent.  virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result);  // This method will be called when an asynchronous write completes on a strea_m.  // One of our asynchronous writes to the remote peer has completed.  // Make sure it succeeded and then delete the message.  virtual ACE_HANDLE handle (void) const;  // Get the I/O handle used by this <handler>. This method will be  // called by the ACE_Asynch_* classes when an ACE_INVALID_HANDLE is  // passed to <open>.  void handle (ACE_HANDLE);  // Set the ACE_HANDLE value for this Handler.  virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask);  // We've been removed from the Reactor.  virtual int handle_output (ACE_HANDLE fd);  // Called when output events should start.  Note that this is  // automatically invoked by the  // <ACE_Reactor_Notificiation_Strategy>.private:  ACE_SOCK_Stream stream_;  // Socket that we have connected to the server.  ACE_Reactor_Notification_Strategy strategy_;  // The strategy object that the reactor uses to notify us when  // something is added to the queue.  // = Remote peer info.  ACE_TCHAR *host_;  // Name of remote host.  u_short port_;  // Port number for remote host.  ACE_Asynch_Read_Stream rd_stream_;  // Read stream  ACE_Asynch_Write_Stream wr_stream_;  // Write stream  ACE_Message_Block mb_;  // Message Block for reading from the network};class STDIN_Handler : public ACE_Task<ACE_NULL_SYNCH>// = TITLE//    Active Object.  Reads from STDIN and passes message blocks to//    the peer handler.{public:  STDIN_Handler (MT_TASK &ph);  // Initialization.  //FUZZ: disable check_for_lack_ACE_OS  virtual int open (void * = 0);  // Activate object.  virtual int close (u_long = 0);  // Shut down.  //FUZZ: enable check_for_lack_ACE_OS  int svc (void);  // Thread runs here as an active object.  int handle_close (ACE_HANDLE,                    ACE_Reactor_Mask);private:  static void handler (int signum);  // Handle a ^C.  (Do nothing, this just illustrates how we can catch  // signals along with the other things).  void register_thread_exit_hook (void);  // Helper function to register with the Reactor for thread exit.  virtual int handle_signal (int index, siginfo_t *, ucontext_t *);  // The STDIN thread has exited.  This means the user hit ^C.  We can  // end the event loop.  MT_TASK &ph_;  // Send all input to ph_.  ACE_HANDLE thr_handle_;  // Handle of our thread.};Peer_Handler::Peer_Handler (int argc, ACE_TCHAR *argv[])  : strategy_ (ACE_Reactor::instance (),               this,               ACE_Event_Handler::WRITE_MASK),    host_ (0),    port_ (ACE_DEFAULT_SERVER_PORT),    mb_ (BUFSIZ){  // This code sets up the message to notify us when a new message is  // added to the queue.  Actually, the queue notifies Reactor which  // then notifies us.  this->msg_queue ()->notification_strategy (&this->strategy_);  ACE_Get_Opt get_opt (argc, argv, ACE_TEXT("h:p:"));  int c;  while ((c = get_opt ()) != EOF)    {      switch (c)        {        case 'h':          host_ = get_opt.opt_arg ();          break;        case 'p':          port_ = ACE_OS::atoi (get_opt.opt_arg ());          break;        }    }}Peer_Handler::~Peer_Handler (void){}// This method creates the network connection to the remote peer.  It// does blocking connects and accepts depending on whether a hostname

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -