• Ubuntu下wxWidgets的CSocket编程,简单聊天室


    服务器端

    /////////////////////////////////////////////////////////////////////////////

    // 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 supportprecompilation, includes "wx/wx.h".

     

    #include "wx/wxprec.h"

    #ifdef __BORLANDC__

    # pragma hdrstop

    #endif

    // for all others, include thenecessary headers

    #ifndef WX_PRECOMP

    # include "wx/wx.h"

    #endif

    #include "wx/busyinfo.h"

    #include "wx/socket.h"

    // this example is currently written touse only IP or only IPv6 sockets, it

    // should be extended to allow usingeither 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 isgoing 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

     DECLARE_EVENT_TABLE()

     

    };

     

    // simple helper class to log start andend 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 menucommands

    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 forwxWidgets

     

    //--------------------------------------------------------------------------

     

     

     

    BEGIN_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)

     

    END_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,

     

                                 _("wxSocketdemo: 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 forconnection Ctrl-W");

     

     m_menuFile->Append(SERVER_UDPTEST, "&UDPtest Ctrl-U");

     

     m_menuFile->AppendSeparator();

     

     m_menuFile->Append(SERVER_ABOUT, _("&About Ctrl-A"),_("Show about dialog"));

     

     m_menuFile->AppendSeparator();

     

     m_menuFile->Append(SERVER_QUIT, _("E&xit Alt-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 towxSocket demo: Server "),

     

                               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

     

     

     

    voidMyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))

     

    {

     

     // true is to force the frame to close

     

     Close(true);

     

    }

     

     

     

    voidMyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))

     

    {

     

     wxMessageBox(_("wxSocket demo: Server (c) 1999 Guillermo RodriguezGarcia "),

     

                   _("About Server"),

     

                   wxOK | wxICON_INFORMATION,this);

     

    }

     

     

     

    voidMyFrame::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;

     

       }

     

    }

     

     

     

    voidMyFrame::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);

     

    }

     

     

     

    voidMyFrame::OnServerEvent(wxSocketEvent& event)

     

    {

     

     wxString s = _("OnServerEvent: ");

     

     wxSocketBase *sock;

     

     

     

     switch(event.GetSocketEvent())

     

     {

     

       case wxSOCKET_CONNECTION :s.Append(_("wxSOCKET_CONNECTION ")); break;

     

       default                  :s.Append(_("Unexpected event ! ")); 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();

     

    }

     

     

     

    voidMyFrame::OnSocketEvent(wxSocketEvent& event)

     

    {

     

     wxString s = _("OnSocketEvent: ");

     

     wxSocketBase *sock = event.GetSocket();

     

     

     

     // First, print a message

     

     switch(event.GetSocketEvent())

     

     {

     

       case wxSOCKET_INPUT : s.Append(_("wxSOCKET_INPUT ")); break;

     

       case wxSOCKET_LOST  :s.Append(_("wxSOCKET_LOST ")); break;

     

       default             :s.Append(_("Unexpected event ! ")); 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 idreceived 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

     

    }

    客户端

    /////////////////////////////////////////////////////////////////////////////

     

    // Name:        client.cpp

     

    // Purpose:     Client for wxSocket demo

     

    // Author:      Guillermo Rodriguez Garcia<guille@iies.es>

     

    // Modified by:

     

    // Created:     1999/09/19

     

    // Copyright:   (c) 1999 Guillermo Rodriguez Garcia

     

    // Licence:     wxWindows licence

     

    /////////////////////////////////////////////////////////////////////////////

     

     

     

    //==========================================================================

     

    // declarations

     

    //==========================================================================

     

     

     

    // --------------------------------------------------------------------------

     

    // headers

     

    //--------------------------------------------------------------------------

     

     

     

    // For compilers that supportprecompilation, includes "wx/wx.h".

     

    #include "wx/wxprec.h"

     

     

     

    #ifdef __BORLANDC__

     

    # pragma hdrstop

     

    #endif

     

     

     

    // for all others, include thenecessary headers

     

    #ifndef WX_PRECOMP

     

    # include "wx/wx.h"

     

    #endif

     

     

     

    #include "wx/socket.h"

     

    #include "wx/url.h"

     

    #include "wx/sstream.h"

     

    #include <memory>

     

     

     

    //--------------------------------------------------------------------------

     

    // 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 isgoing to be our main frame

     

    class MyFrame : public wxFrame

     

    {

     

    public:

     

     MyFrame();

     

     ~MyFrame();

     

     

     

     // event handlers for File menu

     

     void OnQuit(wxCommandEvent& event);

     

     void OnAbout(wxCommandEvent& event);

     

     

     

     // event handlers for Socket menu

     

     void OnOpenConnection(wxCommandEvent& event);

     

     void OnTest1(wxCommandEvent& event);

     

     void OnTest2(wxCommandEvent& event);

     

     void OnTest3(wxCommandEvent& event);

     

     void OnCloseConnection(wxCommandEvent& event);

     

     

     

    #if wxUSE_URL

     

     // event handlers for Protocols menu

     

     void OnTestURL(wxCommandEvent& event);

     

    #endif

     

    #if wxUSE_IPV6

     

     void OnOpenConnectionIPv6(wxCommandEvent& event);

     

    #endif

     

     

     

     void OpenConnection(wxSockAddress::Family family);

     

     

     

     // event handlers for DatagramSocket menu (stub)

     

     void OnDatagram(wxCommandEvent& event);

     

     

     

     // socket event handler

     

     void OnSocketEvent(wxSocketEvent& event);

     

     

     

     // convenience functions

     

     void UpdateStatusBar();

     

     

     

    private:

     

     wxSocketClient *m_sock;

     

     wxTextCtrl     *m_text;

     

     wxMenu         *m_menuFile;

     

     wxMenu         *m_menuSocket;

     

     wxMenu        *m_menuDatagramSocket;

     

     wxMenu         *m_menuProtocols;

     

     wxMenuBar      *m_menuBar;

     

     bool            m_busy;

     

     

     

     // any class wishing to process wxWidgets events must use this macro

     

     DECLARE_EVENT_TABLE()

     

    };

     

     

     

    // simple helper class to log start andend of each test

     

    class TestLogger

     

    {

     

    public:

     

       TestLogger(const wxString& name) : m_name(name)

     

       {

     

           wxLogMessage("=== %s test begins ===", m_name);

     

       }

     

     

     

       ~TestLogger()

     

       {

     

           wxLogMessage("=== %s test ends ===", m_name);

     

       }

     

     

     

    private:

     

       const wxString m_name;

     

    };

     

     

     

    //--------------------------------------------------------------------------

     

    // constants

     

    //--------------------------------------------------------------------------

     

     

     

    // IDs for the controls and the menucommands

     

    enum

     

    {

     

     // menu items

     

     CLIENT_QUIT = wxID_EXIT,

     

     CLIENT_ABOUT = wxID_ABOUT,

     

     CLIENT_OPEN = 100,

     

    #if wxUSE_IPV6

     

     CLIENT_OPENIPV6,

     

    #endif

     

     CLIENT_TEST1,

     

     CLIENT_TEST2,

     

     CLIENT_TEST3,

     

     CLIENT_CLOSE,

     

    #if wxUSE_URL

     

     CLIENT_TESTURL,

     

    #endif

     

     CLIENT_DGRAM,

     

     

     

     // id for socket

     

     SOCKET_ID

     

    };

     

     

     

    //--------------------------------------------------------------------------

     

    // event tables and other macros forwxWidgets

     

    //--------------------------------------------------------------------------

     

     

     

    BEGIN_EVENT_TABLE(MyFrame, wxFrame)

     

     EVT_MENU(CLIENT_QUIT,    MyFrame::OnQuit)

     

     EVT_MENU(CLIENT_ABOUT,   MyFrame::OnAbout)

     

     EVT_MENU(CLIENT_OPEN,    MyFrame::OnOpenConnection)

     

    #if wxUSE_IPV6

     

     EVT_MENU(CLIENT_OPENIPV6, MyFrame::OnOpenConnectionIPv6)

     

    #endif

     

     EVT_MENU(CLIENT_TEST1,   MyFrame::OnTest1)

     

     EVT_MENU(CLIENT_TEST2,   MyFrame::OnTest2)

     

     EVT_MENU(CLIENT_TEST3,   MyFrame::OnTest3)

     

     EVT_MENU(CLIENT_CLOSE,   MyFrame::OnCloseConnection)

     

     EVT_MENU(CLIENT_DGRAM,   MyFrame::OnDatagram)

     

    #if wxUSE_URL

     

     EVT_MENU(CLIENT_TESTURL, MyFrame::OnTestURL)

     

    #endif

     

     EVT_SOCKET(SOCKET_ID,    MyFrame::OnSocketEvent)

     

    END_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,

     

                                _("wxSocketdemo: Client"),

     

                                 wxDefaultPosition,wxSize(300, 200))

     

    {

     

     // Give the frame an icon

     

     //SetIcon(wxICON(sample));

     

     

     

     // Make menus

     

     m_menuFile = new wxMenu();

     

     m_menuFile->Append(CLIENT_ABOUT, _("&About Ctrl-A"),_("Show about dialog"));

     

     m_menuFile->AppendSeparator();

     

     m_menuFile->Append(CLIENT_QUIT, _("E&xit Alt-X"),_("Quit client"));

     

     

     

     m_menuSocket = new wxMenu();

     

     m_menuSocket->Append(CLIENT_OPEN, _("&Open session Ctrl-O"),_("Connect to server"));

     

    #if wxUSE_IPV6

     

     m_menuSocket->Append(CLIENT_OPENIPV6, _("&Opensession(IPv6) Shift-Ctrl-O"), _("Connect to server(IPv6)"));

     

    #endif

     

     m_menuSocket->AppendSeparator();

     

     m_menuSocket->Append(CLIENT_TEST1, _("Test&1 Ctrl-F1"), _("Test basic functionality"));

     

     m_menuSocket->Append(CLIENT_TEST2, _("Test&2 Ctrl-F2"), _("Test ReadMsg and WriteMsg"));

     

     m_menuSocket->Append(CLIENT_TEST3, _("Test&3 Ctrl-F3"), _("Test large data transfer"));

     

     m_menuSocket->AppendSeparator();

     

     m_menuSocket->Append(CLIENT_CLOSE, _("&Closesession Ctrl-Q"), _("Close connection"));

     

     

     

     m_menuDatagramSocket = new wxMenu();

     

     m_menuDatagramSocket->Append(CLIENT_DGRAM, _("&Datagramtest Ctrl-D"), _("Test UDP sockets"));

     

     

     

    #if wxUSE_URL

     

     m_menuProtocols = new wxMenu();

     

     m_menuProtocols->Append(CLIENT_TESTURL, _("TestURL Ctrl-U"),

     

                              _("Get data fromthe specified URL"));

     

    #endif

     

     

     

     // Append menus to the menubar

     

     m_menuBar = new wxMenuBar();

     

     m_menuBar->Append(m_menuFile, _("&File"));

     

     m_menuBar->Append(m_menuSocket, _("&TCP"));

     

     m_menuBar->Append(m_menuDatagramSocket, _("&UDP"));

     

    #if wxUSE_URL

     

     m_menuBar->Append(m_menuProtocols, _("&Protocols"));

     

    #endif

     

     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 towxSocket demo: Client Client ready "),

     

                               wxDefaultPosition,wxDefaultSize,

     

                               wxTE_MULTILINE |wxTE_READONLY);

     

     delete wxLog::SetActiveTarget(new wxLogTextCtrl(m_text));

     

     

     

     // Create the socket

     

     m_sock = new wxSocketClient();

     

     

     

     // Setup the event handler and subscribe to most events

     

     m_sock->SetEventHandler(*this, SOCKET_ID);

     

     m_sock->SetNotify(wxSOCKET_CONNECTION_FLAG |

     

                        wxSOCKET_INPUT_FLAG |

     

                        wxSOCKET_LOST_FLAG);

     

     m_sock->Notify(true);

     

     

     

     m_busy = false;

     

     UpdateStatusBar();

     

    }

     

     

     

    MyFrame::~MyFrame()

     

    {

     

     // No delayed deletion here, as the frame is dying anyway

     

     delete m_sock;

     

    }

     

     

     

    // event handlers

     

     

     

    voidMyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))

     

    {

     

     // true is to force the frame to close

     

     Close(true);

     

    }

     

     

     

    voidMyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))

     

    {

     

     wxMessageBox(_("wxSocket demo: Client (c) 1999 Guillermo RodriguezGarcia "),

     

                   _("About Client"),

     

                   wxOK | wxICON_INFORMATION,this);

     

    }

     

     

     

    voidMyFrame::OnOpenConnection(wxCommandEvent& WXUNUSED(event))

     

    {

     

       OpenConnection(wxSockAddress::IPV4);

     

    }

     

    #if wxUSE_IPV6

     

    voidMyFrame::OnOpenConnectionIPv6(wxCommandEvent& WXUNUSED(event))

     

    {

     

       OpenConnection(wxSockAddress::IPV6);

     

    }

     

    #endif // wxUSE_IPV6

     

     

     

    voidMyFrame::OpenConnection(wxSockAddress::Family family)

     

    {

     

       wxUnusedVar(family); // unused in !wxUSE_IPV6 case

     

     

     

     wxIPaddress * addr;

     

     wxIPV4address addr4;

     

    #if wxUSE_IPV6

     

     wxIPV6address addr6;

     

     if ( family == wxSockAddress::IPV6 )

     

       addr = &addr6;

     

     else

     

    #endif

     

       addr = &addr4;

     

     

     

     m_menuSocket->Enable(CLIENT_OPEN, false);

     

    #if wxUSE_IPV6

     

     m_menuSocket->Enable(CLIENT_OPENIPV6, false);

     

    #endif

     

     m_menuSocket->Enable(CLIENT_CLOSE, false);

     

     

     

     // Ask user for server address

     

     wxString hostname = wxGetTextFromUser(

     

       _("Enter the address of the wxSocket demo server:"),

     

       _("Connect ..."),

     

       _("localhost"));

     

     if ( hostname.empty() )

     

       return;

     

     

     

     addr->Hostname(hostname);

     

     addr->Service(3000);

     

     

     

     // we connect asynchronously and will get a wxSOCKET_CONNECTION eventwhen

     

     // the connection is really established

     

     //

     

     // if you want to make sure that connection is established right hereyou

     

     // could call WaitOnConnect(timeout) instead

     

     wxLogMessage("Trying to connect to %s:%d", hostname,addr->Service());

     

     

     

     m_sock->Connect(*addr, false);

     

    }

     

     

     

    void MyFrame::OnTest1(wxCommandEvent&WXUNUSED(event))

     

    {

     

     // Disable socket menu entries (exception: Close Session)

     

     m_busy = true;

     

     UpdateStatusBar();

     

     

     

     m_text->AppendText(_(" === Test 1 begins === "));

     

     

     

     // Tell the server which test we are running

     

     unsigned char c = 0xBE;

     

     m_sock->Write(&c, 1);

     

     

     

     // Send some data and read it back. We know the size of the

     

     // buffer, so we can specify the exact number of bytes to be

     

     // sent or received and use the wxSOCKET_WAITALL flag. Also,

     

     // we have disabled menu entries which could interfere with

     

     // the test, so we can safely avoid the wxSOCKET_BLOCK flag.

     

     //

     

     // First we send a byte with the length of the string, then

     

     // we send the string itself (do NOT try to send any integral

     

     // value larger than a byte "as is" across the network, or

     

     // you might be in trouble! Ever heard about big and little

     

     // endian computers?)

     

     

     

     m_sock->SetFlags(wxSOCKET_WAITALL);

     

     

     

     const char *buf1 = "Test string (less than 256 chars!)";

     

     unsigned char len  = (unsignedchar)(wxStrlen(buf1) + 1);

     

     wxCharBuffer buf2(wxStrlen(buf1));

     

     

     

     m_text->AppendText(_("Sending a test buffer to the server..."));

     

     m_sock->Write(&len, 1);

     

     m_sock->Write(buf1, len);

     

     m_text->AppendText(m_sock->Error() ? _("failed ! ") :_("done "));

     

     

     

     m_text->AppendText(_("Receiving the buffer back from server..."));

     

     m_sock->Read(buf2.data(), len);

     

     m_text->AppendText(m_sock->Error() ? _("failed ! ") :_("done "));

     

     

     

     m_text->AppendText(_("Comparing the two buffers ..."));

     

     if (memcmp(buf1, buf2, len) != 0)

     

     {

     

       m_text->AppendText(_("failed! "));

     

       m_text->AppendText(_("Test 1 failed ! "));

     

     }

     

     else

     

     {

     

       m_text->AppendText(_("done "));

     

       m_text->AppendText(_("Test 1 passed ! "));

     

     }

     

     m_text->AppendText(_("=== Test 1 ends === "));

     

     

     

     m_busy = false;

     

     UpdateStatusBar();

     

    }

     

     

     

    voidMyFrame::OnTest2(wxCommandEvent& WXUNUSED(event))

     

    {

     

     // Disable socket menu entries (exception: Close Session)

     

     m_busy = true;

     

     UpdateStatusBar();

     

     

     

     m_text->AppendText(_(" === Test 2 begins === "));

     

     

     

     // Tell the server which test we are running

     

     unsigned char c = 0xCE;

     

     m_sock->Write(&c, 1);

     

     

     

     // Here we use ReadMsg and WriteMsg to send messages with

     

     // a header with size information. Also, the reception is

     

     // event triggered, so we test input events as well.

     

     //

     

     // We need to set no flags here (ReadMsg and WriteMsg are

     

     // not affected by flags)

     

     

     

     m_sock->SetFlags(wxSOCKET_WAITALL);

     

     

     

     wxString s = wxGetTextFromUser(

     

       _("Enter an arbitrary string to send to the server:"),

     

       _("Test 2 ..."),

     

       _("Yes I like wxWidgets!"));

     

     

     

     const wxScopedCharBuffer msg1(s.utf8_str());

     

     size_t len  = wxStrlen(msg1) + 1;

     

     wxCharBuffer msg2(wxStrlen(msg1));

     

     

     

     m_text->AppendText(_("Sending the string with WriteMsg..."));

     

     m_sock->WriteMsg(msg1, len);

     

     m_text->AppendText(m_sock->Error() ? _("failed ! ") :_("done "));

     

     m_text->AppendText(_("Waiting for an event (timeout = 2sec) "));

     

     

     

     // Wait until data available (will also return if the connection islost)

     

     m_sock->WaitForRead(2);

     

     

     

     if (m_sock->IsData())

     

     {

     

       m_text->AppendText(_("Reading the string back with ReadMsg..."));

     

       m_sock->ReadMsg(msg2.data(), len);

     

       m_text->AppendText(m_sock->Error() ? _("failed ! ") :_("done "));

     

       m_text->AppendText(_("Comparing the two buffers ..."));

     

       if (memcmp(msg1, msg2, len) != 0)

     

       {

     

         m_text->AppendText(_("failed! "));

     

         m_text->AppendText(_("Test 2 failed ! "));

     

       }

     

       else

     

       {

     

         m_text->AppendText(_("done "));

     

         m_text->AppendText(_("Test 2 passed ! "));

     

       }

     

     }

     

     else

     

       m_text->AppendText(_("Timeout ! Test 2 failed. "));

     

     

     

     m_text->AppendText(_("=== Test 2 ends === "));

     

     

     

     m_busy = false;

     

     UpdateStatusBar();

     

    }

     

     

     

    voidMyFrame::OnTest3(wxCommandEvent& WXUNUSED(event))

     

    {

     

     // Disable socket menu entries (exception: Close Session)

     

     m_busy = true;

     

     UpdateStatusBar();

     

     

     

     m_text->AppendText(_(" === Test 3 begins === "));

     

     

     

     // Tell the server which test we are running

     

     unsigned char c = 0xDE;

     

     m_sock->Write(&c, 1);

     

     

     

     // This test also is similar to the first one but it sends a

     

     // large buffer so that wxSocket is actually forced to split

     

     // it into pieces and take care of sending everything before

     

     // returning.

     

     

     

     m_sock->SetFlags(wxSOCKET_WAITALL);

     

     

     

     // Note that len is in kbytes here!

     

     const unsigned char len  = 32;

     

     wxCharBuffer buf1(len * 1024),

     

                   buf2(len * 1024);

     

     

     

     for (size_t i = 0; i < len * 1024; i ++)

     

       buf1.data()[i] = (char)(i % 256);

     

     

     

     m_text->AppendText(_("Sending a large buffer (32K) to the server..."));

     

     m_sock->Write(&len, 1);

     

     m_sock->Write(buf1, len * 1024);

     

     m_text->AppendText(m_sock->Error() ? _("failed ! ") :_("done "));

     

     

     

     m_text->AppendText(_("Receiving the buffer back from server..."));

     

     m_sock->Read(buf2.data(), len * 1024);

     

     m_text->AppendText(m_sock->Error() ? _("failed ! ") :_("done "));

     

     

     

     m_text->AppendText(_("Comparing the two buffers ..."));

     

     if (memcmp(buf1, buf2, len) != 0)

     

     {

     

       m_text->AppendText(_("failed! "));

     

       m_text->AppendText(_("Test 3 failed ! "));

     

     }

     

     else

     

     {

     

       m_text->AppendText(_("done "));

     

       m_text->AppendText(_("Test 3 passed ! "));

     

     }

     

     m_text->AppendText(_("=== Test 3 ends === "));

     

     

     

     m_busy = false;

     

     UpdateStatusBar();

     

    }

     

     

     

    voidMyFrame::OnCloseConnection(wxCommandEvent& WXUNUSED(event))

     

    {

     

     m_sock->Close();

     

     UpdateStatusBar();

     

    }

     

     

     

    voidMyFrame::OnDatagram(wxCommandEvent& WXUNUSED(event))

     

    {

     

       wxString hostname = wxGetTextFromUser

     

                            (

     

                             "Enter theaddress of the wxSocket demo server:",

     

                             "UDP peer",

     

                             "localhost"

     

                            );

     

       if ( hostname.empty() )

     

           return;

     

     

     

       TestLogger logtest("UDP");

     

     

     

       wxIPV4address addrLocal;

     

       addrLocal.Hostname();

     

       wxDatagramSocket sock(addrLocal);

     

       if ( !sock.IsOk() )

     

       {

     

           wxLogMessage("ERROR: failed to create UDP socket");

     

           return;

     

       }

     

     

     

       wxLogMessage("Created UDP socket at %s:%u",

     

                     addrLocal.IPAddress(),addrLocal.Service());

     

     

     

       wxIPV4address addrPeer;

     

       addrPeer.Hostname(hostname);

     

       addrPeer.Service(3000);

     

     

     

       wxLogMessage("Testing UDP with peer at %s:%u",

     

                     addrPeer.IPAddress(),addrPeer.Service());

     

     

     

       char buf[] = "Uryyb sebz pyvrag!";

     

       if ( sock.SendTo(addrPeer, buf, sizeof(buf)).LastCount() != sizeof(buf))

     

       {

     

           wxLogMessage("ERROR: failed to send data");

     

           return;

     

       }

     

     

     

       if ( sock.RecvFrom(addrPeer, buf, sizeof(buf)).LastCount() !=sizeof(buf) )

     

       {

     

           wxLogMessage("ERROR: failed to receive data");

     

           return;

     

       }

     

     

     

       wxLogMessage("Received "%s" from %s:%u.",

     

                     wxString::From8BitData(buf,sock.LastCount()),

     

                     addrPeer.IPAddress(),addrPeer.Service());

     

    }

     

     

     

    #if wxUSE_URL

     

     

     

    voidMyFrame::OnTestURL(wxCommandEvent& WXUNUSED(event))

     

    {

     

       // Ask for the URL

     

       static wxString s_urlname("http://www.google.com/");

     

       wxString urlname = wxGetTextFromUser

     

                           (

     

                            _("Enter an URL toget"),

     

                            _("URL:"),

     

                            s_urlname

     

                           );

     

       if ( urlname.empty() )

     

           return; // cancelled by user

     

     

     

       s_urlname = urlname;

     

     

     

     

     

       TestLogger logtest("URL");

     

     

     

       // Parse the URL

     

       wxURL url(urlname);

     

       if ( url.GetError() != wxURL_NOERR )

     

       {

     

           wxLogError("Failed to parse URL "%s"", urlname);

     

           return;

     

       }

     

     

     

       // Try to get the input stream (connects to the given URL)

     

       wxLogMessage("Establishing connection to "%s"...",urlname);

     

       const std::auto_ptr<wxInputStream> data(url.GetInputStream());

     

       if ( !data.get() )

     

       {

     

           wxLogError("Failed to retrieve URL "%s"",urlname);

     

           return;

     

       }

     

     

     

       // Print the contents type and file size

     

       wxLogMessage("Contents type: %s File size: %lu Starting todownload...",

     

                    url.GetProtocol().GetContentType(),

     

                     static_cast<unsignedlong>( data->GetSize() ));

     

     

     

       // Get the data

     

       wxStringOutputStream sout;

     

       if ( data->Read(sout).GetLastError() != wxSTREAM_EOF )

     

       {

     

           wxLogError("Error reading the input stream.");

     

       }

     

     

     

       wxLogMessage("Text retrieved from URL "%s"follows: %s",

     

                     urlname, sout.GetString());

     

    }

     

     

     

    #endif // wxUSE_URL

     

     

     

    voidMyFrame::OnSocketEvent(wxSocketEvent& event)

     

    {

     

       switch ( event.GetSocketEvent() )

     

       {

     

           case wxSOCKET_INPUT:

     

                wxLogMessage("Input availableon the socket");

     

                break;

     

     

     

           case wxSOCKET_LOST:

     

                wxLogMessage("Socketconnection was unexpectedly lost.");

     

                UpdateStatusBar();

     

                break;

     

     

     

           case wxSOCKET_CONNECTION:

     

                wxLogMessage("... socket isnow connected.");

     

                UpdateStatusBar();

     

                break;

     

     

     

           default:

     

                wxLogMessage("Unknown socketevent!!!");

     

                break;

     

       }

     

    }

     

     

     

    // convenience functions

     

     

     

    void MyFrame::UpdateStatusBar()

     

    {

     

    #if wxUSE_STATUSBAR

     

     wxString s;

     

     

     

     if (!m_sock->IsConnected())

     

     {

     

       s = "Not connected";

     

     }

     

     else

     

     {

     

    #if wxUSE_IPV6

     

       wxIPV6address addr;

     

    #else

     

       wxIPV4address addr;

     

    #endif

     

     

     

       m_sock->GetPeer(addr);

     

       s.Printf("%s : %d", addr.Hostname(), addr.Service());

     

     }

     

     

     

     SetStatusText(s, 1);

     

    #endif // wxUSE_STATUSBAR

     

     

     

     m_menuSocket->Enable(CLIENT_OPEN, !m_sock->IsConnected()&& !m_busy);

     

    #if wxUSE_IPV6

     

     m_menuSocket->Enable(CLIENT_OPENIPV6, !m_sock->IsConnected()&& !m_busy);

     

    #endif

     

     m_menuSocket->Enable(CLIENT_TEST1, m_sock->IsConnected()&& !m_busy);

     

     m_menuSocket->Enable(CLIENT_TEST2, m_sock->IsConnected()&& !m_busy);

     

     m_menuSocket->Enable(CLIENT_TEST3, m_sock->IsConnected()&& !m_busy);

     

     m_menuSocket->Enable(CLIENT_CLOSE, m_sock->IsConnected());

     

    }

     

  • 相关阅读:
    python函数名和左括号之间不能有空格
    linux版本选择
    filter_map
    awk统计总结
    Spring Boot + Redis 实现各种操作
    手机号正则校验
    判断windows系统
    Redis分布式锁
    shell 脚本快速部署 SpringBoot 项目
    Java主流的Http请求--原生的HttpURLConnection
  • 原文地址:https://www.cnblogs.com/zhangaihua/p/3718086.html
Copyright © 2020-2023  润新知