]>
git.saurik.com Git - wxWidgets.git/blob - samples/wxsocket/client.cpp
1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Client for wxSocket demo
4 // Author: Guillermo Rodriguez Garcia <guille@iies.es>
8 // Copyright: (c) 1999 Guillermo Rodriguez Garcia
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ==========================================================================
14 // ==========================================================================
16 // --------------------------------------------------------------------------
18 // --------------------------------------------------------------------------
21 # pragma implementation "client.cpp"
22 # pragma interface "client.cpp"
25 // For compilers that support precompilation, includes "wx/wx.h".
26 #include "wx/wxprec.h"
32 // for all others, include the necessary headers
35 # include "wx/socket.h"
37 # include "wx/protocol/http.h"
38 # include "wx/progdlg.h"
41 // --------------------------------------------------------------------------
43 // --------------------------------------------------------------------------
45 // the application icon
46 #if defined(__WXGTK__) || defined(__WXMOTIF__)
47 # include "mondrian.xpm"
50 // --------------------------------------------------------------------------
52 // --------------------------------------------------------------------------
54 // Define a new application type
55 class MyApp
: public wxApp
58 virtual bool OnInit();
61 // Define a new frame type: this is going to be our main frame
62 class MyFrame
: public wxFrame
68 // event handlers (these functions should _not_ be virtual)
69 void OnQuit(wxCommandEvent
& event
);
70 void OnAbout(wxCommandEvent
& event
);
71 void OnOpenConnection(wxCommandEvent
& event
);
72 void OnTest1(wxCommandEvent
& event
);
73 void OnTest2(wxCommandEvent
& event
);
74 void OnTest3(wxCommandEvent
& event
);
75 void OnCloseConnection(wxCommandEvent
& event
);
76 void OnSocketEvent(wxSocketEvent
& event
);
78 // convenience functions
79 void UpdateStatusBar();
82 wxSocketClient
*m_sock
;
90 // any class wishing to process wxWindows events must use this macro
94 // --------------------------------------------------------------------------
96 // --------------------------------------------------------------------------
98 // IDs for the controls and the menu commands
114 // --------------------------------------------------------------------------
115 // event tables and other macros for wxWindows
116 // --------------------------------------------------------------------------
118 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
119 EVT_MENU(CLIENT_QUIT
, MyFrame::OnQuit
)
120 EVT_MENU(CLIENT_ABOUT
, MyFrame::OnAbout
)
121 EVT_MENU(CLIENT_OPEN
, MyFrame::OnOpenConnection
)
122 EVT_MENU(CLIENT_TEST1
, MyFrame::OnTest1
)
123 EVT_MENU(CLIENT_TEST2
, MyFrame::OnTest2
)
124 EVT_MENU(CLIENT_TEST3
, MyFrame::OnTest3
)
125 EVT_MENU(CLIENT_CLOSE
, MyFrame::OnCloseConnection
)
126 EVT_SOCKET(SOCKET_ID
, MyFrame::OnSocketEvent
)
131 // ==========================================================================
133 // ==========================================================================
135 // --------------------------------------------------------------------------
136 // the application class
137 // --------------------------------------------------------------------------
141 // Create the main application window
142 MyFrame
*frame
= new MyFrame();
144 // Show it and tell the application that it's our main window
152 // --------------------------------------------------------------------------
154 // --------------------------------------------------------------------------
157 MyFrame::MyFrame() : wxFrame((wxFrame
*)NULL
, -1,
158 _T("wxSocket demo: Client"),
159 wxDefaultPosition
, wxSize(300, 200))
161 // Give the frame an icon
162 SetIcon(wxICON(mondrian
));
165 m_menuFile
= new wxMenu();
166 m_menuFile
->Append(CLIENT_ABOUT
, _T("&About...\tCtrl-A"), _T("Show about dialog"));
167 m_menuFile
->AppendSeparator();
168 m_menuFile
->Append(CLIENT_QUIT
, _T("E&xit\tAlt-X"), _T("Quit client"));
170 m_menuSocket
= new wxMenu();
171 m_menuSocket
->Append(CLIENT_OPEN
, _T("&Open session"), _T("Connect to server"));
172 m_menuSocket
->AppendSeparator();
173 m_menuSocket
->Append(CLIENT_TEST1
, _T("Test &1"), _T("Test basic functionality"));
174 m_menuSocket
->Append(CLIENT_TEST2
, _T("Test &2"), _T("Test ReadMsg and WriteMsg"));
175 m_menuSocket
->Append(CLIENT_TEST3
, _T("Test &3"), _T("Test large data transfer"));
176 m_menuSocket
->AppendSeparator();
177 m_menuSocket
->Append(CLIENT_CLOSE
, _T("&Close session"), _T("Close connection"));
179 // Append menus to the menubar
180 m_menuBar
= new wxMenuBar();
181 m_menuBar
->Append(m_menuFile
, _T("&File"));
182 m_menuBar
->Append(m_menuSocket
, _T("&Socket"));
183 SetMenuBar(m_menuBar
);
188 // Make a panel with a textctrl in it
189 m_panel
= new wxPanel(this, -1, wxPoint(0, 0), GetClientSize());
190 m_text
= new wxTextCtrl(m_panel
, -1,
191 _T("Welcome to wxSocket demo: Client\n")
192 _T("Client ready\n\n"),
193 wxPoint(0, 0), m_panel
->GetClientSize(),
194 wxTE_MULTILINE
| wxTE_READONLY
);
197 m_sock
= new wxSocketClient();
198 m_sock
->SetEventHandler(*this, SOCKET_ID
);
199 m_sock
->SetNotify(wxSOCKET_CONNECTION_FLAG
|
200 wxSOCKET_INPUT_FLAG
|
202 m_sock
->Notify(TRUE
);
215 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
217 // TRUE is to force the frame to close
221 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
223 wxMessageBox(_T("wxSocket demo: Client\n")
224 _T("(c) 1999 Guillermo Rodriguez Garcia\n"),
226 wxOK
| wxICON_INFORMATION
, this);
229 void MyFrame::OnOpenConnection(wxCommandEvent
& WXUNUSED(event
))
233 m_menuSocket
->Enable(CLIENT_OPEN
, FALSE
);
234 m_menuSocket
->Enable(CLIENT_CLOSE
, FALSE
);
236 // Ask server address
237 wxString hostname
= wxGetTextFromUser(
238 _T("Enter the address of the wxSocket demo server:"),
242 addr
.Hostname(hostname
);
245 // Non-blocking connect
246 m_text
->AppendText(_T("Trying to connect (timeout = 10 sec) ...\n"));
247 m_sock
->Connect(addr
, FALSE
);
248 m_sock
->WaitOnConnect(10);
250 if (m_sock
->IsConnected())
251 m_text
->AppendText(_T("Succeeded ! Connection established\n"));
255 m_text
->AppendText(_T("Failed ! Unable to connect\n"));
256 wxMessageBox(_T("Can't connect to the specified host"), _T("Alert !"));
262 void MyFrame::OnTest1(wxCommandEvent
& WXUNUSED(event
))
267 // Disable socket menu entries (exception: Close Session)
271 m_text
->AppendText(_T("\n=== Test 1 begins ===\n"));
273 // Tell the server which test we are running
275 m_sock
->Write(&c
, 1);
277 // Send some data and read it back. We know the size of the
278 // buffer, so we can specify the exact number of bytes to be
279 // sent or received and use the WAITALL flag. Also, we have
280 // disabled menu entries which could interfere with the test,
281 // so we can safely avoid the BLOCK (formerly SPEED) flag.
283 // First we send a byte with the length of the string, then
284 // we send the string itself (do NOT try to send any integral
285 // value larger than a byte "as is" acrosss the network, or
286 // you might be in trouble! Ever heard about big and little
287 // endian computers?)
289 m_sock
->SetFlags(wxSOCKET_WAITALL
);
291 buf1
= _T("Test string (less than 127 chars!)");
292 len
= wxStrlen(buf1
) + 1;
293 buf2
= new char[len
];
295 m_text
->AppendText(_T("Sending a test buffer to the server ..."));
296 m_sock
->Write(&len
, 1);
297 m_sock
->Write(buf1
, len
);
298 m_text
->AppendText(m_sock
->Error() ? _T("failed !\n") : _T("done\n"));
300 m_text
->AppendText(_T("Receiving the buffer back from server ..."));
301 m_sock
->Read(buf2
, len
);
302 m_text
->AppendText(m_sock
->Error() ? _T("failed !\n") : _T("done\n"));
304 m_text
->AppendText(_T("Comparing the two buffers ..."));
305 if (memcmp(buf1
, buf2
, len
) != 0)
307 m_text
->AppendText(_T("failed!\n"));
308 m_text
->AppendText(_T("Test 1 failed !\n"));
312 m_text
->AppendText(_T("done\n"));
313 m_text
->AppendText(_T("Test 1 passed !\n"));
315 m_text
->AppendText(_T("=== Test 1 ends ===\n"));
322 void MyFrame::OnTest2(wxCommandEvent
& WXUNUSED(event
))
328 // Disable socket menu entries (exception: Close Session)
332 m_text
->AppendText(_T("\n=== Test 2 begins ===\n"));
334 // Tell the server which test we are running
336 m_sock
->Write(&c
, 1);
338 // Here we use ReadMsg and WriteMsg to send messages with
339 // a header with size information. Also, the reception is
340 // event triggered, so we test input events as well.
342 // We need to set no flags here (ReadMsg and WriteMsg are
343 // not affected by flags)
345 m_sock
->SetFlags(wxSOCKET_WAITALL
);
347 wxString s
= wxGetTextFromUser(
348 _T("Enter an arbitrary string to send to the server:"),
350 _T("Yes I like wxWindows!"));
352 msg1
= (char *)s
.c_str();
353 len
= wxStrlen(msg1
) + 1;
354 msg2
= (char *)malloc(len
);
356 m_text
->AppendText(_T("Sending the string with WriteMsg ..."));
357 m_sock
->WriteMsg(msg1
, len
);
358 m_text
->AppendText(m_sock
->Error() ? _T("failed !\n") : _T("done\n"));
359 m_text
->AppendText(_T("Waiting for an event (timeout = 2 sec)\n"));
361 // Wait until data available (will also return if the connection is lost)
362 m_sock
->WaitForRead(2);
364 if (m_sock
->IsData())
366 m_text
->AppendText(_T("Reading the string back with ReadMsg ..."));
367 m_sock
->ReadMsg(msg2
, len
);
368 m_text
->AppendText(m_sock
->Error() ? _T("failed !\n") : _T("done\n"));
369 m_text
->AppendText(_T("Comparing the two buffers ..."));
370 if (memcmp(msg1
, msg2
, len
) != 0)
372 m_text
->AppendText(_T("failed!\n"));
373 m_text
->AppendText(_T("Test 2 failed !\n"));
377 m_text
->AppendText(_T("done\n"));
378 m_text
->AppendText(_T("Test 2 passed !\n"));
382 m_text
->AppendText(_T("Timeout ! Test 2 failed.\n"));
384 m_text
->AppendText(_T("=== Test 2 ends ===\n"));
391 void MyFrame::OnTest3(wxCommandEvent
& WXUNUSED(event
))
393 m_text
->AppendText(_T("\n=== Test 3 begins ===\n"));
394 m_text
->AppendText(_T("Test 3 not implemented\n"));
395 m_text
->AppendText(_T("=== Test 3 ends ===\n"));
398 void MyFrame::OnCloseConnection(wxCommandEvent
& WXUNUSED(event
))
404 void MyFrame::OnSocketEvent(wxSocketEvent
& event
)
406 wxString s
= _T("OnSocketEvent: ");
408 switch(event
.SocketEvent())
410 case wxSOCKET_INPUT
: s
.Append(_T("wxSOCKET_INPUT\n")); break;
411 case wxSOCKET_LOST
: s
.Append(_T("wxSOCKET_LOST\n")); break;
412 case wxSOCKET_CONNECTION
: s
.Append(_T("wxSOCKET_CONNECTION\n")); break;
413 default : s
.Append(_T("Unexpected event !\n")); break;
416 m_text
->AppendText(s
);
420 // convenience functions
422 void MyFrame::UpdateStatusBar()
426 if (!m_sock
->IsConnected())
428 s
.Printf(_T("Not connected"));
434 m_sock
->GetPeer(addr
);
435 s
.Printf(_T("%s : %d"), (addr
.Hostname()).c_str(), addr
.Service());
440 m_menuSocket
->Enable(CLIENT_OPEN
, !m_sock
->IsConnected() && !m_busy
);
441 m_menuSocket
->Enable(CLIENT_TEST1
, m_sock
->IsConnected() && !m_busy
);
442 m_menuSocket
->Enable(CLIENT_TEST2
, m_sock
->IsConnected() && !m_busy
);
443 m_menuSocket
->Enable(CLIENT_TEST3
, m_sock
->IsConnected() && !m_busy
);
444 m_menuSocket
->Enable(CLIENT_CLOSE
, m_sock
->IsConnected());