]> git.saurik.com Git - wxWidgets.git/blame - samples/wxsocket/client.cpp
bugfixes
[wxWidgets.git] / samples / wxsocket / client.cpp
CommitLineData
f4ada568
GL
1/*
2 * File: client.cpp
3 * Purpose: wxSocket: client demo
e2a6f233 4 * Author: LAVAUX Guilhem
f4ada568 5 * Created: June 1997
062c4861 6 * CVS ID: $Id$
e2a6f233 7 * Copyright: (c) 1997, LAVAUX Guilhem
f4ada568 8 */
e2a6f233 9
f4ada568
GL
10#ifdef __GNUG__
11#pragma implementation
12#pragma interface
13#endif
14
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
18#ifdef __BORLANDC__
19#pragma hdrstop
20#endif
21
22#ifndef WX_PRECOMP
23#include "wx/wx.h"
24#endif
e2a6f233 25
a737331d 26#include "wx/wfstream.h"
f4ada568
GL
27#include "wx/socket.h"
28#include "wx/url.h"
29#include "wx/protocol/http.h"
6b3eb77a 30#include "wx/thread.h"
a324a7bc 31#include "wx/progdlg.h"
f4ada568 32
e2a6f233
JS
33#if defined(__WXMOTIF__) || defined(__WXGTK__)
34#include "mondrian.xpm"
35#endif
36
f4ada568
GL
37// Define a new application type
38class MyApp: public wxApp
39{ public:
40 virtual bool OnInit(void);
41};
42
43class MyClient;
44
45// Define a new frame type
46class MyFrame: public wxFrame
47{
48 DECLARE_CLASS(MyFrame)
49public:
50 MyClient *sock;
765e386b 51 int m_good;
f4ada568
GL
52
53 MyFrame(void);
54 virtual ~MyFrame();
55 void OnCloseTest(wxCommandEvent& evt);
56 void OnExecTest1(wxCommandEvent& evt);
57 void OnExecUrlTest(wxCommandEvent& evt);
58 void OnQuitApp(wxCommandEvent& evt);
59 void OnExecOpenConnection(wxCommandEvent& evt);
60 void OnExecCloseConnection(wxCommandEvent& evt);
765e386b 61 void OnSocketEvent(wxSocketEvent& evt);
f4ada568
GL
62 void UpdateStatus();
63
a324a7bc
GL
64 void Download(wxInputStream *input);
65
f4ada568
GL
66 DECLARE_EVENT_TABLE()
67};
68
69
70IMPLEMENT_CLASS(MyFrame, wxFrame)
71
72/*
73 * Define a new derived SocketClient
74 */
75class MyClient: public wxSocketClient
76{
77public:
78 MyFrame *frame;
79
a324a7bc 80 void OnNotify(GSocketEventFlags WXUNUSED(flags)) { frame->UpdateStatus(); }
f4ada568
GL
81};
82
83// ID for the menu quit command
db131261
RR
84const int SKDEMO_QUIT = 101;
85const int SKDEMO_CONNECT = 102;
86const int SKDEMO_TEST1 = 103;
87const int SKDEMO_TEST2 = 104;
88const int SKDEMO_CLOSE = 105;
89const int SKDEMO_TEST3 = 106;
90const int ID_TEST_CLOSE = 107;
765e386b 91const int SKDEMO_SCK = 108;
f4ada568
GL
92
93IMPLEMENT_APP(MyApp)
94
95/*
96 * `Main program' equivalent, creating windows and returning main app frame
97 */
98bool MyApp::OnInit(void)
99{
100 // Create the main frame window
101 MyFrame *frame = new MyFrame();
102
103 // Give it an icon
e2a6f233 104 frame->SetIcon(wxICON(mondrian));
f4ada568
GL
105
106 // Make a menubar
107 wxMenu *file_menu = new wxMenu();
108
109 file_menu->Append(SKDEMO_QUIT, "Exit");
110 wxMenuBar *menu_bar = new wxMenuBar;
111 menu_bar->Append(file_menu, "File");
112
113 wxMenu *socket_menu = new wxMenu();
114 socket_menu->Append(SKDEMO_CONNECT, "Open session");
115 socket_menu->AppendSeparator();
116 socket_menu->Append(SKDEMO_TEST1, "Start test 1");
f4ada568
GL
117 socket_menu->AppendSeparator();
118 socket_menu->Append(SKDEMO_CLOSE, "Close session");
119 socket_menu->AppendSeparator();
120 socket_menu->Append(SKDEMO_TEST3, "Start URL test");
121
122 menu_bar->Append(socket_menu, "Socket");
123
124 frame->SetMenuBar(menu_bar);
125
126 // Make a panel with a message
e2a6f233 127 (void)new wxPanel(frame, -1, wxPoint(0, 0), wxSize(300, 100));
f4ada568
GL
128
129 // Show the frame
130 frame->Show(TRUE);
131
132 // Return the main frame window
27529614 133 return TRUE;
f4ada568
GL
134}
135
136/*
137 * MyFrame Constructor
138 */
139MyFrame::MyFrame():
140 wxFrame(NULL, -1, "wxSocket client demo",
141 wxDefaultPosition, wxSize(300, 200), wxDEFAULT_FRAME_STYLE)
142{
f4ada568 143 sock = new MyClient();
9111db68 144 sock->SetFlags((wxSocketBase::wxSockFlags) (wxSocketBase::WAITALL | wxSocketBase::SPEED));
f4ada568 145 sock->frame = this;
2618484f 146 sock->SetNotify(wxSOCKET_LOST_FLAG);
f4ada568
GL
147 CreateStatusBar(2);
148 UpdateStatus();
149}
150
151MyFrame::~MyFrame()
152{
153 delete sock;
154}
155
156void MyFrame::OnQuitApp(wxCommandEvent& WXUNUSED(evt))
157{
158 Close(TRUE);
159}
160
161void MyFrame::OnExecOpenConnection(wxCommandEvent& WXUNUSED(evt))
162{
163 wxIPV4address addr;
164
165 if (sock->IsConnected())
166 sock->Close();
167
168 wxString hname = wxGetTextFromUser("Enter the address of the wxSocket Sample Server",
169 "Connect ...", "localhost");
170 addr.Hostname(hname);
171 addr.Service(3000);
11235b74
GRG
172 sock->Connect(addr, FALSE);
173 sock->WaitOnConnect(10);
a324a7bc 174 sock->SetFlags(wxSocketBase::NONE);
f4ada568
GL
175 if (!sock->IsConnected())
176 wxMessageBox("Can't connect to the specified host", "Alert !");
177
178 UpdateStatus();
179}
180
181void MyFrame::OnExecCloseConnection(wxCommandEvent& WXUNUSED(evt))
182{
a324a7bc 183 sock->Close();
f4ada568
GL
184 UpdateStatus();
185}
186
187BEGIN_EVENT_TABLE(MyFrame, wxFrame)
188 EVT_BUTTON(ID_TEST_CLOSE, MyFrame::OnCloseTest)
189 EVT_MENU(SKDEMO_TEST1, MyFrame::OnExecTest1)
190 EVT_MENU(SKDEMO_TEST3, MyFrame::OnExecUrlTest)
191 EVT_MENU(SKDEMO_QUIT, MyFrame::OnQuitApp)
192 EVT_MENU(SKDEMO_CONNECT, MyFrame::OnExecOpenConnection)
193 EVT_MENU(SKDEMO_CLOSE, MyFrame::OnExecCloseConnection)
765e386b 194 EVT_SOCKET(SKDEMO_SCK, MyFrame::OnSocketEvent)
f4ada568
GL
195END_EVENT_TABLE()
196
765e386b
GL
197class MyFrameSocketTimer: public wxTimer {
198 public:
199 void Notify() {
200 *m_var = 0;
201 }
202
203 int *m_var;
204};
205
206void MyFrame::OnSocketEvent(wxSocketEvent& evt)
207{
208 m_good = 1;
209}
210
f4ada568
GL
211void MyFrame::OnCloseTest(wxCommandEvent& evt)
212{
213 wxButton *button = (wxButton *)evt.GetEventObject();
214 wxDialog *dlg = (wxDialog *)button->GetParent();
215
216 dlg->EndModal(0);
217}
218
219void MyFrame::UpdateStatus()
220{
221 if (!sock->IsConnected()) {
222 SetStatusText("Not connected", 0);
223 SetStatusText("", 1);
224 } else {
225 wxIPV4address addr;
a737331d 226 wxChar s[100];
f4ada568
GL
227
228 sock->GetPeer(addr);
a737331d 229 wxSprintf(s, _T("Connected to %s"), WXSTRINGCAST addr.Hostname());
f4ada568 230 SetStatusText(s, 0);
a737331d 231 wxSprintf(s, _T("Service: %d"), addr.Service());
f4ada568
GL
232 SetStatusText(s, 1);
233 }
234}
235
236void MyFrame::OnExecTest1(wxCommandEvent& WXUNUSED(evt))
237{
238 if (!sock->IsConnected())
239 return;
240
11235b74 241 wxDialog *dlgbox = new wxDialog(this, -1, "Test 1", wxDefaultPosition, wxSize(414, 280));
f4ada568
GL
242 wxTextCtrl *text_win = new wxTextCtrl(dlgbox, -1, "",
243 wxPoint(0, 0), wxSize(400, 200),
244 wxTE_MULTILINE);
245 (void)new wxButton(dlgbox, ID_TEST_CLOSE, "Close",
db131261 246 wxPoint(100, 210), wxSize(100, -1));
a737331d 247 wxChar *buf, *buf2;
f4ada568
GL
248
249 dlgbox->Layout();
250 dlgbox->Show(TRUE);
251
252 text_win->WriteText("Initializing test 1 ...\n");
253
db131261
RR
254 wxYield();
255
f4ada568 256 /* Init */
a737331d
GL
257 buf = copystring(_T("Hi ! Hi ! Hi !\n"));
258 buf2 = new wxChar[wxStrlen(buf)+1];
f4ada568 259 char c = 0xbe;
a737331d 260 sock->Write(&c, 1);
f4ada568
GL
261
262 /* No 1 */
263 text_win->WriteText("Sending some byte to the server ...");
a737331d
GL
264 wxYield();
265 sock->Write((char *)buf, wxStrlen(buf)+1);
f4ada568 266 text_win->WriteText("done\n");
a737331d 267 wxYield();
f4ada568 268 text_win->WriteText("Receiving some byte from the server ...");
a737331d
GL
269 wxYield();
270 sock->Read((char *)buf2, wxStrlen(buf)+1);
f4ada568 271 text_win->WriteText("done\n");
a737331d 272 wxYield();
f4ada568
GL
273
274 text_win->WriteText("Comparing the two buffers ...");
a737331d 275 if (memcmp(buf, buf2, wxStrlen(buf)+1) != 0) {
f4ada568
GL
276 text_win->WriteText("Fail\n");
277 sock->Close();
278 UpdateStatus();
279 } else
765e386b
GL
280 text_win->WriteText("done\nTest 1A passed !\n");
281
282 /* No 2 */
283 sock->SetEventHandler(*this, SKDEMO_SCK);
2618484f 284 sock->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
765e386b 285 sock->Notify(TRUE);
765e386b 286 text_win->WriteText("Test 1B: sending bytes to the server\n");
83802b0b
GRG
287 if (!sock->IsData())
288 text_win->WriteText("No data to read yet (this is OK)\n");
289
765e386b
GL
290 wxYield();
291 sock->Write((char *)buf, wxStrlen(buf)+1);
292 text_win->WriteText("Waiting for incoming bytes (timeout = 2 sec) ...");
293 wxYield();
294
295 m_good = 2;
296
297 MyFrameSocketTimer timer;
298
299 timer.m_var = &m_good;
300 timer.Start(2000, TRUE);
301
302 while (m_good == 2)
303 wxYield();
304
305 if (!m_good) {
83802b0b 306 text_win->WriteText("timeout ! Failed.\n");
765e386b
GL
307 sock->Close();
308 UpdateStatus();
309 } else
83802b0b
GRG
310 text_win->WriteText("event ! (no timeout).\n");
311
312 if (sock->IsData())
313 text_win->WriteText("Data is available, as expected...\n");
765e386b
GL
314
315 sock->Read((char *)buf2, wxStrlen(buf)+1);
f4ada568 316
83802b0b
GRG
317 text_win->WriteText("Success!\n");
318
f4ada568
GL
319 dlgbox->Layout();
320 dlgbox->ShowModal();
321
322 delete [] buf;
323 delete [] buf2;
324 delete text_win;
325 delete dlgbox;
326}
327
a324a7bc
GL
328
329void MyFrame::Download(wxInputStream *input)
330{
331 wxProgressDialog progress("Downloading ...", "0% downloaded");
a324a7bc 332 wxFileOutputStream f_out("test.url");
a324a7bc 333 size_t downloaded;
f61815af
GL
334 int BUFSIZE, bytes_read;
335 size_t file_size;
a324a7bc
GL
336 wxString message;
337 int percents;
338
339 char *buf;
340
f61815af
GL
341 if (input->GetSize() == (size_t)-1) {
342 file_size = (size_t)-1;
343 bytes_read = BUFSIZE = 10240;
344 } else {
345 file_size = input->GetSize();
346 if (file_size > 10240)
347 bytes_read = BUFSIZE = file_size / 1024;
348 else
349 bytes_read = BUFSIZE = 1024;
350 }
a324a7bc
GL
351 buf = new char[BUFSIZE];
352
353 downloaded = 0;
354 bytes_read = BUFSIZE;
355 while (downloaded < file_size && bytes_read != 0) {
f61815af 356 bytes_read = input->Read(buf, BUFSIZE).LastRead();
a324a7bc
GL
357 f_out.Write(buf, bytes_read);
358 downloaded += bytes_read;
359
360 percents = downloaded * 100 / file_size;
361
362 message = _T("");
363 message << percents << _T("% downloaded");
364 progress.Update(percents, message);
365 }
366
367 delete[] buf;
368}
369
f4ada568
GL
370void MyFrame::OnExecUrlTest(wxCommandEvent& WXUNUSED(evt))
371{
856d2e52
GL
372 wxString urlname = wxGetTextFromUser("Enter an URL to get",
373 "URL:", "http://localhost");
f4ada568
GL
374
375 wxURL url(urlname);
376 wxInputStream *datas = url.GetInputStream();
377
062c4861
GL
378 if (!datas) {
379 wxString error;
380 error.Printf(_T("Error in getting data from the URL. (error = %d)"), url.GetError());
381 wxMessageBox(error, "Alert !");
382 } else {
a324a7bc 383 Download(datas);
a737331d 384
f4ada568
GL
385 delete datas;
386 }
387}