18f42b94df
It is definitely not necessary to call SetTopWindow() when there is only a single top level window and it is arguable whether it's useful to do it even when there are many of them so don't encourage its use in the documentation and also remove all its occurrences from the samples. Closes #12816. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66528 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
691 lines
19 KiB
C++
691 lines
19 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: client.cpp
|
|
// Purpose: Client for wxSocket demo
|
|
// Author: Guillermo Rodriguez Garcia <guille@iies.es>
|
|
// Modified by:
|
|
// Created: 1999/09/19
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) 1999 Guillermo Rodriguez Garcia
|
|
// 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/socket.h"
|
|
#include "wx/url.h"
|
|
#include "wx/sstream.h"
|
|
#include <memory>
|
|
|
|
// --------------------------------------------------------------------------
|
|
// resources
|
|
// --------------------------------------------------------------------------
|
|
|
|
// the application icon
|
|
#if !defined(__WXMSW__) && !defined(__WXPM__)
|
|
#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 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 and end 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 menu commands
|
|
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 for wxWidgets
|
|
// --------------------------------------------------------------------------
|
|
|
|
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,
|
|
_("wxSocket demo: 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...\tCtrl-A"), _("Show about dialog"));
|
|
m_menuFile->AppendSeparator();
|
|
m_menuFile->Append(CLIENT_QUIT, _("E&xit\tAlt-X"), _("Quit client"));
|
|
|
|
m_menuSocket = new wxMenu();
|
|
m_menuSocket->Append(CLIENT_OPEN, _("&Open session\tCtrl-O"), _("Connect to server"));
|
|
#if wxUSE_IPV6
|
|
m_menuSocket->Append(CLIENT_OPENIPV6, _("&Open session(IPv6)\tShift-Ctrl-O"), _("Connect to server(IPv6)"));
|
|
#endif
|
|
m_menuSocket->AppendSeparator();
|
|
m_menuSocket->Append(CLIENT_TEST1, _("Test &1\tCtrl-F1"), _("Test basic functionality"));
|
|
m_menuSocket->Append(CLIENT_TEST2, _("Test &2\tCtrl-F2"), _("Test ReadMsg and WriteMsg"));
|
|
m_menuSocket->Append(CLIENT_TEST3, _("Test &3\tCtrl-F3"), _("Test large data transfer"));
|
|
m_menuSocket->AppendSeparator();
|
|
m_menuSocket->Append(CLIENT_CLOSE, _("&Close session\tCtrl-Q"), _("Close connection"));
|
|
|
|
m_menuDatagramSocket = new wxMenu();
|
|
m_menuDatagramSocket->Append(CLIENT_DGRAM, _("&Datagram test\tCtrl-D"), _("Test UDP sockets"));
|
|
|
|
#if wxUSE_URL
|
|
m_menuProtocols = new wxMenu();
|
|
m_menuProtocols->Append(CLIENT_TESTURL, _("Test URL\tCtrl-U"),
|
|
_("Get data from the 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 to wxSocket demo: Client\nClient ready\n"),
|
|
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
|
|
|
|
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: Client\n(c) 1999 Guillermo Rodriguez Garcia\n"),
|
|
_("About Client"),
|
|
wxOK | wxICON_INFORMATION, this);
|
|
}
|
|
|
|
void MyFrame::OnOpenConnection(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
OpenConnection(wxSockAddress::IPV4);
|
|
}
|
|
#if wxUSE_IPV6
|
|
void MyFrame::OnOpenConnectionIPv6(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
OpenConnection(wxSockAddress::IPV6);
|
|
}
|
|
#endif // wxUSE_IPV6
|
|
|
|
void MyFrame::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 event when
|
|
// the connection is really established
|
|
//
|
|
// if you want to make sure that connection is established right here you
|
|
// 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(_("\n=== Test 1 begins ===\n"));
|
|
|
|
// 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 = (unsigned char)(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 !\n") : _("done\n"));
|
|
|
|
m_text->AppendText(_("Receiving the buffer back from server ..."));
|
|
m_sock->Read(buf2.data(), len);
|
|
m_text->AppendText(m_sock->Error() ? _("failed !\n") : _("done\n"));
|
|
|
|
m_text->AppendText(_("Comparing the two buffers ..."));
|
|
if (memcmp(buf1, buf2, len) != 0)
|
|
{
|
|
m_text->AppendText(_("failed!\n"));
|
|
m_text->AppendText(_("Test 1 failed !\n"));
|
|
}
|
|
else
|
|
{
|
|
m_text->AppendText(_("done\n"));
|
|
m_text->AppendText(_("Test 1 passed !\n"));
|
|
}
|
|
m_text->AppendText(_("=== Test 1 ends ===\n"));
|
|
|
|
m_busy = false;
|
|
UpdateStatusBar();
|
|
}
|
|
|
|
void MyFrame::OnTest2(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
// Disable socket menu entries (exception: Close Session)
|
|
m_busy = true;
|
|
UpdateStatusBar();
|
|
|
|
m_text->AppendText(_("\n=== Test 2 begins ===\n"));
|
|
|
|
// 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 !\n") : _("done\n"));
|
|
m_text->AppendText(_("Waiting for an event (timeout = 2 sec)\n"));
|
|
|
|
// Wait until data available (will also return if the connection is lost)
|
|
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 !\n") : _("done\n"));
|
|
m_text->AppendText(_("Comparing the two buffers ..."));
|
|
if (memcmp(msg1, msg2, len) != 0)
|
|
{
|
|
m_text->AppendText(_("failed!\n"));
|
|
m_text->AppendText(_("Test 2 failed !\n"));
|
|
}
|
|
else
|
|
{
|
|
m_text->AppendText(_("done\n"));
|
|
m_text->AppendText(_("Test 2 passed !\n"));
|
|
}
|
|
}
|
|
else
|
|
m_text->AppendText(_("Timeout ! Test 2 failed.\n"));
|
|
|
|
m_text->AppendText(_("=== Test 2 ends ===\n"));
|
|
|
|
m_busy = false;
|
|
UpdateStatusBar();
|
|
}
|
|
|
|
void MyFrame::OnTest3(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
// Disable socket menu entries (exception: Close Session)
|
|
m_busy = true;
|
|
UpdateStatusBar();
|
|
|
|
m_text->AppendText(_("\n=== Test 3 begins ===\n"));
|
|
|
|
// 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 !\n") : _("done\n"));
|
|
|
|
m_text->AppendText(_("Receiving the buffer back from server ..."));
|
|
m_sock->Read(buf2.data(), len * 1024);
|
|
m_text->AppendText(m_sock->Error() ? _("failed !\n") : _("done\n"));
|
|
|
|
m_text->AppendText(_("Comparing the two buffers ..."));
|
|
if (memcmp(buf1, buf2, len) != 0)
|
|
{
|
|
m_text->AppendText(_("failed!\n"));
|
|
m_text->AppendText(_("Test 3 failed !\n"));
|
|
}
|
|
else
|
|
{
|
|
m_text->AppendText(_("done\n"));
|
|
m_text->AppendText(_("Test 3 passed !\n"));
|
|
}
|
|
m_text->AppendText(_("=== Test 3 ends ===\n"));
|
|
|
|
m_busy = false;
|
|
UpdateStatusBar();
|
|
}
|
|
|
|
void MyFrame::OnCloseConnection(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
m_sock->Close();
|
|
UpdateStatusBar();
|
|
}
|
|
|
|
void MyFrame::OnDatagram(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxString hostname = wxGetTextFromUser
|
|
(
|
|
"Enter the address 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
|
|
|
|
void MyFrame::OnTestURL(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
// Ask for the URL
|
|
static wxString s_urlname("http://www.google.com/");
|
|
wxString urlname = wxGetTextFromUser
|
|
(
|
|
_("Enter an URL to get"),
|
|
_("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\nFile size: %i\nStarting to download...",
|
|
url.GetProtocol().GetContentType(),
|
|
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:\n%s",
|
|
urlname, sout.GetString());
|
|
}
|
|
|
|
#endif // wxUSE_URL
|
|
|
|
void MyFrame::OnSocketEvent(wxSocketEvent& event)
|
|
{
|
|
switch ( event.GetSocketEvent() )
|
|
{
|
|
case wxSOCKET_INPUT:
|
|
wxLogMessage("Input available on the socket");
|
|
break;
|
|
|
|
case wxSOCKET_LOST:
|
|
wxLogMessage("Socket connection was unexpectedly lost.");
|
|
UpdateStatusBar();
|
|
break;
|
|
|
|
case wxSOCKET_CONNECTION:
|
|
wxLogMessage("... socket is now connected.");
|
|
UpdateStatusBar();
|
|
break;
|
|
|
|
default:
|
|
wxLogMessage("Unknown socket event!!!");
|
|
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());
|
|
}
|