| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 | 
							- /////////////////////////////////////////////////////////////////////////////
 
- // Name:        server.cpp
 
- // Purpose:     Server for wxSocket demo
 
- // Author:      Guillermo Rodriguez Garcia <guille@iies.es>
 
- // Created:     1999/09/19
 
- // Copyright:   (c) 1999 Guillermo Rodriguez Garcia
 
- //              (c) 2009 Vadim Zeitlin
 
- // Licence:     wxWindows licence
 
- /////////////////////////////////////////////////////////////////////////////
 
- // ==========================================================================
 
- // declarations
 
- // ==========================================================================
 
- // --------------------------------------------------------------------------
 
- // headers
 
- // --------------------------------------------------------------------------
 
- // For compilers that support precompilation, includes "wx/wx.h".
 
- #include "wx/wxprec.h"
 
- #ifdef __BORLANDC__
 
- #  pragma hdrstop
 
- #endif
 
- // for all others, include the necessary headers
 
- #ifndef WX_PRECOMP
 
- #  include "wx/wx.h"
 
- #endif
 
- #include "wx/busyinfo.h"
 
- #include "wx/socket.h"
 
- // this example is currently written to use only IP or only IPv6 sockets, it
 
- // should be extended to allow using either in the future
 
- #if wxUSE_IPV6
 
-     typedef wxIPV6address IPaddress;
 
- #else
 
-     typedef wxIPV4address IPaddress;
 
- #endif
 
- // --------------------------------------------------------------------------
 
- // resources
 
- // --------------------------------------------------------------------------
 
- // the application icon
 
- #ifndef wxHAS_IMAGES_IN_RESOURCES
 
-     #include "../sample.xpm"
 
- #endif
 
- // --------------------------------------------------------------------------
 
- // classes
 
- // --------------------------------------------------------------------------
 
- // Define a new application type
 
- class MyApp : public wxApp
 
- {
 
- public:
 
-   virtual bool OnInit();
 
- };
 
- // Define a new frame type: this is going to be our main frame
 
- class MyFrame : public wxFrame
 
- {
 
- public:
 
-   MyFrame();
 
-   ~MyFrame();
 
-   // event handlers (these functions should _not_ be virtual)
 
-   void OnUDPTest(wxCommandEvent& event);
 
-   void OnWaitForAccept(wxCommandEvent& event);
 
-   void OnQuit(wxCommandEvent& event);
 
-   void OnAbout(wxCommandEvent& event);
 
-   void OnServerEvent(wxSocketEvent& event);
 
-   void OnSocketEvent(wxSocketEvent& event);
 
-   void Test1(wxSocketBase *sock);
 
-   void Test2(wxSocketBase *sock);
 
-   void Test3(wxSocketBase *sock);
 
-   // convenience functions
 
-   void UpdateStatusBar();
 
- private:
 
-   wxSocketServer *m_server;
 
-   wxTextCtrl     *m_text;
 
-   wxMenu         *m_menuFile;
 
-   wxMenuBar      *m_menuBar;
 
-   bool            m_busy;
 
-   int             m_numClients;
 
-   // any class wishing to process wxWidgets events must use this macro
 
-   wxDECLARE_EVENT_TABLE();
 
- };
 
- // simple helper class to log start and end of each test
 
- class TestLogger
 
- {
 
- public:
 
-     TestLogger(const wxString& name) : m_name(name)
 
-     {
 
-         wxLogMessage("=== %s begins ===", m_name);
 
-     }
 
-     ~TestLogger()
 
-     {
 
-         wxLogMessage("=== %s ends ===", m_name);
 
-     }
 
- private:
 
-     const wxString m_name;
 
- };
 
- // --------------------------------------------------------------------------
 
- // constants
 
- // --------------------------------------------------------------------------
 
- // IDs for the controls and the menu commands
 
- enum
 
- {
 
-   // menu items
 
-   SERVER_UDPTEST = 10,
 
-   SERVER_WAITFORACCEPT,
 
-   SERVER_QUIT = wxID_EXIT,
 
-   SERVER_ABOUT = wxID_ABOUT,
 
-   // id for sockets
 
-   SERVER_ID = 100,
 
-   SOCKET_ID
 
- };
 
- // --------------------------------------------------------------------------
 
- // event tables and other macros for wxWidgets
 
- // --------------------------------------------------------------------------
 
- wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
 
-   EVT_MENU(SERVER_QUIT,  MyFrame::OnQuit)
 
-   EVT_MENU(SERVER_ABOUT, MyFrame::OnAbout)
 
-   EVT_MENU(SERVER_UDPTEST, MyFrame::OnUDPTest)
 
-   EVT_MENU(SERVER_WAITFORACCEPT, MyFrame::OnWaitForAccept)
 
-   EVT_SOCKET(SERVER_ID,  MyFrame::OnServerEvent)
 
-   EVT_SOCKET(SOCKET_ID,  MyFrame::OnSocketEvent)
 
- wxEND_EVENT_TABLE()
 
- IMPLEMENT_APP(MyApp)
 
- // ==========================================================================
 
- // implementation
 
- // ==========================================================================
 
- // --------------------------------------------------------------------------
 
- // the application class
 
- // --------------------------------------------------------------------------
 
- bool MyApp::OnInit()
 
- {
 
-   if ( !wxApp::OnInit() )
 
-       return false;
 
-   // Create the main application window
 
-   MyFrame *frame = new MyFrame();
 
-   // Show it
 
-   frame->Show(true);
 
-   // Success
 
-   return true;
 
- }
 
- // --------------------------------------------------------------------------
 
- // main frame
 
- // --------------------------------------------------------------------------
 
- // frame constructor
 
- MyFrame::MyFrame() : wxFrame((wxFrame *)NULL, wxID_ANY,
 
-                              _("wxSocket demo: Server"),
 
-                              wxDefaultPosition, wxSize(300, 200))
 
- {
 
-   // Give the frame an icon
 
-   SetIcon(wxICON(sample));
 
-   // Make menus
 
-   m_menuFile = new wxMenu();
 
-   m_menuFile->Append(SERVER_WAITFORACCEPT, "&Wait for connection\tCtrl-W");
 
-   m_menuFile->Append(SERVER_UDPTEST, "&UDP test\tCtrl-U");
 
-   m_menuFile->AppendSeparator();
 
-   m_menuFile->Append(SERVER_ABOUT, _("&About\tCtrl-A"), _("Show about dialog"));
 
-   m_menuFile->AppendSeparator();
 
-   m_menuFile->Append(SERVER_QUIT, _("E&xit\tAlt-X"), _("Quit server"));
 
-   // Append menus to the menubar
 
-   m_menuBar = new wxMenuBar();
 
-   m_menuBar->Append(m_menuFile, _("&File"));
 
-   SetMenuBar(m_menuBar);
 
- #if wxUSE_STATUSBAR
 
-   // Status bar
 
-   CreateStatusBar(2);
 
- #endif // wxUSE_STATUSBAR
 
-   // Make a textctrl for logging
 
-   m_text  = new wxTextCtrl(this, wxID_ANY,
 
-                            _("Welcome to wxSocket demo: Server\n"),
 
-                            wxDefaultPosition, wxDefaultSize,
 
-                            wxTE_MULTILINE | wxTE_READONLY);
 
-   delete wxLog::SetActiveTarget(new wxLogTextCtrl(m_text));
 
-   // Create the address - defaults to localhost:0 initially
 
-   IPaddress addr;
 
-   addr.Service(3000);
 
-   wxLogMessage("Creating server at %s:%u", addr.IPAddress(), addr.Service());
 
-   // Create the socket
 
-   m_server = new wxSocketServer(addr);
 
-   // We use IsOk() here to see if the server is really listening
 
-   if (! m_server->IsOk())
 
-   {
 
-     wxLogMessage("Could not listen at the specified port !");
 
-     return;
 
-   }
 
-   IPaddress addrReal;
 
-   if ( !m_server->GetLocal(addrReal) )
 
-   {
 
-     wxLogMessage("ERROR: couldn't get the address we bound to");
 
-   }
 
-   else
 
-   {
 
-     wxLogMessage("Server listening at %s:%u",
 
-                  addrReal.IPAddress(), addrReal.Service());
 
-   }
 
-   // Setup the event handler and subscribe to connection events
 
-   m_server->SetEventHandler(*this, SERVER_ID);
 
-   m_server->SetNotify(wxSOCKET_CONNECTION_FLAG);
 
-   m_server->Notify(true);
 
-   m_busy = false;
 
-   m_numClients = 0;
 
-   UpdateStatusBar();
 
- }
 
- MyFrame::~MyFrame()
 
- {
 
-   // No delayed deletion here, as the frame is dying anyway
 
-   delete m_server;
 
- }
 
- // event handlers
 
- void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
 
- {
 
-   // true is to force the frame to close
 
-   Close(true);
 
- }
 
- void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 
- {
 
-   wxMessageBox(_("wxSocket demo: Server\n(c) 1999 Guillermo Rodriguez Garcia\n"),
 
-                _("About Server"),
 
-                wxOK | wxICON_INFORMATION, this);
 
- }
 
- void MyFrame::OnUDPTest(wxCommandEvent& WXUNUSED(event))
 
- {
 
-     TestLogger logtest("UDP test");
 
-     IPaddress addr;
 
-     addr.Service(3000);
 
-     wxDatagramSocket sock(addr);
 
-     char buf[1024];
 
-     size_t n = sock.RecvFrom(addr, buf, sizeof(buf)).LastCount();
 
-     if ( !n )
 
-     {
 
-         wxLogMessage("ERROR: failed to receive data");
 
-         return;
 
-     }
 
-     wxLogMessage("Received \"%s\" from %s:%u.",
 
-                  wxString::From8BitData(buf, n),
 
-                  addr.IPAddress(), addr.Service());
 
-     for ( size_t i = 0; i < n; i++ )
 
-     {
 
-         char& c = buf[i];
 
-         if ( (c >= 'A' && c <= 'M') || (c >= 'a' && c <= 'm') )
 
-             c += 13;
 
-         else if ( (c >= 'N' && c <= 'Z') || (c >= 'n' && c <= 'z') )
 
-             c -= 13;
 
-     }
 
-     if ( sock.SendTo(addr, buf, n).LastCount() != n )
 
-     {
 
-         wxLogMessage("ERROR: failed to send data");
 
-         return;
 
-     }
 
- }
 
- void MyFrame::OnWaitForAccept(wxCommandEvent& WXUNUSED(event))
 
- {
 
-     TestLogger logtest("WaitForAccept() test");
 
-     wxBusyInfo("Waiting for connection for 10 seconds...", this);
 
-     if ( m_server->WaitForAccept(10) )
 
-         wxLogMessage("Accepted client connection.");
 
-     else
 
-         wxLogMessage("Connection error or timeout expired.");
 
- }
 
- void MyFrame::Test1(wxSocketBase *sock)
 
- {
 
-   TestLogger logtest("Test 1");
 
-   // Receive data from socket and send it back. We will first
 
-   // get a byte with the buffer size, so we can specify the
 
-   // exact size and use the wxSOCKET_WAITALL flag. Also, we
 
-   // disabled input events so we won't have unwanted reentrance.
 
-   // This way we can avoid the infamous wxSOCKET_BLOCK flag.
 
-   sock->SetFlags(wxSOCKET_WAITALL);
 
-   // Read the size
 
-   unsigned char len;
 
-   sock->Read(&len, 1);
 
-   wxCharBuffer buf(len);
 
-   // Read the data
 
-   sock->Read(buf.data(), len);
 
-   wxLogMessage("Got the data, sending it back");
 
-   // Write it back
 
-   sock->Write(buf, len);
 
- }
 
- void MyFrame::Test2(wxSocketBase *sock)
 
- {
 
-   char buf[4096];
 
-   TestLogger logtest("Test 2");
 
-   // We don't need to set flags because ReadMsg and WriteMsg
 
-   // are not affected by them anyway.
 
-   // Read the message
 
-   wxUint32 len = sock->ReadMsg(buf, sizeof(buf)).LastCount();
 
-   if ( !len )
 
-   {
 
-       wxLogError("Failed to read message.");
 
-       return;
 
-   }
 
-   wxLogMessage("Got \"%s\" from client.", wxString::FromUTF8(buf, len));
 
-   wxLogMessage("Sending the data back");
 
-   // Write it back
 
-   sock->WriteMsg(buf, len);
 
- }
 
- void MyFrame::Test3(wxSocketBase *sock)
 
- {
 
-   TestLogger logtest("Test 3");
 
-   // This test is similar to the first one, but the len is
 
-   // expressed in kbytes - this tests large data transfers.
 
-   sock->SetFlags(wxSOCKET_WAITALL);
 
-   // Read the size
 
-   unsigned char len;
 
-   sock->Read(&len, 1);
 
-   wxCharBuffer buf(len*1024);
 
-   // Read the data
 
-   sock->Read(buf.data(), len * 1024);
 
-   wxLogMessage("Got the data, sending it back");
 
-   // Write it back
 
-   sock->Write(buf, len * 1024);
 
- }
 
- void MyFrame::OnServerEvent(wxSocketEvent& event)
 
- {
 
-   wxString s = _("OnServerEvent: ");
 
-   wxSocketBase *sock;
 
-   switch(event.GetSocketEvent())
 
-   {
 
-     case wxSOCKET_CONNECTION : s.Append(_("wxSOCKET_CONNECTION\n")); break;
 
-     default                  : s.Append(_("Unexpected event !\n")); break;
 
-   }
 
-   m_text->AppendText(s);
 
-   // Accept new connection if there is one in the pending
 
-   // connections queue, else exit. We use Accept(false) for
 
-   // non-blocking accept (although if we got here, there
 
-   // should ALWAYS be a pending connection).
 
-   sock = m_server->Accept(false);
 
-   if (sock)
 
-   {
 
-     IPaddress addr;
 
-     if ( !sock->GetPeer(addr) )
 
-     {
 
-       wxLogMessage("New connection from unknown client accepted.");
 
-     }
 
-     else
 
-     {
 
-       wxLogMessage("New client connection from %s:%u accepted",
 
-                    addr.IPAddress(), addr.Service());
 
-     }
 
-   }
 
-   else
 
-   {
 
-     wxLogMessage("Error: couldn't accept a new connection");
 
-     return;
 
-   }
 
-   sock->SetEventHandler(*this, SOCKET_ID);
 
-   sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
 
-   sock->Notify(true);
 
-   m_numClients++;
 
-   UpdateStatusBar();
 
- }
 
- void MyFrame::OnSocketEvent(wxSocketEvent& event)
 
- {
 
-   wxString s = _("OnSocketEvent: ");
 
-   wxSocketBase *sock = event.GetSocket();
 
-   // First, print a message
 
-   switch(event.GetSocketEvent())
 
-   {
 
-     case wxSOCKET_INPUT : s.Append(_("wxSOCKET_INPUT\n")); break;
 
-     case wxSOCKET_LOST  : s.Append(_("wxSOCKET_LOST\n")); break;
 
-     default             : s.Append(_("Unexpected event !\n")); break;
 
-   }
 
-   m_text->AppendText(s);
 
-   // Now we process the event
 
-   switch(event.GetSocketEvent())
 
-   {
 
-     case wxSOCKET_INPUT:
 
-     {
 
-       // We disable input events, so that the test doesn't trigger
 
-       // wxSocketEvent again.
 
-       sock->SetNotify(wxSOCKET_LOST_FLAG);
 
-       // Which test are we going to run?
 
-       unsigned char c;
 
-       sock->Read(&c, 1);
 
-       switch (c)
 
-       {
 
-         case 0xBE: Test1(sock); break;
 
-         case 0xCE: Test2(sock); break;
 
-         case 0xDE: Test3(sock); break;
 
-         default:
 
-           wxLogMessage("Unknown test id received from client");
 
-       }
 
-       // Enable input events again.
 
-       sock->SetNotify(wxSOCKET_LOST_FLAG | wxSOCKET_INPUT_FLAG);
 
-       break;
 
-     }
 
-     case wxSOCKET_LOST:
 
-     {
 
-       m_numClients--;
 
-       // Destroy() should be used instead of delete wherever possible,
 
-       // due to the fact that wxSocket uses 'delayed events' (see the
 
-       // documentation for wxPostEvent) and we don't want an event to
 
-       // arrive to the event handler (the frame, here) after the socket
 
-       // has been deleted. Also, we might be doing some other thing with
 
-       // the socket at the same time; for example, we might be in the
 
-       // middle of a test or something. Destroy() takes care of all
 
-       // this for us.
 
-       wxLogMessage("Deleting socket.");
 
-       sock->Destroy();
 
-       break;
 
-     }
 
-     default: ;
 
-   }
 
-   UpdateStatusBar();
 
- }
 
- // convenience functions
 
- void MyFrame::UpdateStatusBar()
 
- {
 
- #if wxUSE_STATUSBAR
 
-   wxString s;
 
-   s.Printf(_("%d clients connected"), m_numClients);
 
-   SetStatusText(s, 1);
 
- #endif // wxUSE_STATUSBAR
 
- }
 
 
  |