]> git.saurik.com Git - wxWidgets.git/blob - samples/wxsocket/server.cpp
Small bug fix
[wxWidgets.git] / samples / wxsocket / server.cpp
1 /*
2 * File: server.cpp
3 * Purpose: wxSocket: server demo
4 * Author: LAVAUX Guilhem
5 * Created: June 1997
6 * CVS Id: $Id$
7 * Copyright: (C) 1997, LAVAUX Guilhem
8 */
9
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
25
26 #include "wx/socket.h"
27 #include "wx/thread.h"
28
29 #if defined(__WXMOTIF__) || defined(__WXGTK__)
30 #include "mondrian.xpm"
31 #endif
32
33 // Define a new application type
34 class MyApp: public wxApp
35 { public:
36 bool OnInit(void);
37 };
38
39 class MyServer;
40
41 // Define a new frame type
42 class MyFrame: public wxFrame
43 {
44 DECLARE_EVENT_TABLE()
45 public:
46 wxSocketServer *sock;
47 int nb_clients;
48
49 MyFrame(wxFrame *frame);
50 virtual ~MyFrame();
51 void Menu_Exit(wxCommandEvent& evt);
52 void OnSockRequest(wxSocketEvent& evt);
53 void OnSockRequestServer(wxSocketEvent& evt);
54 void ExecTest1(wxSocketBase *sock_o);
55 void UpdateStatus(int incr);
56 };
57
58 #define SKDEMO_QUIT 101
59 #define SKDEMO_SOCKET_SERV 102
60 #define SKDEMO_SOCKET 103
61
62 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
63 EVT_MENU(SKDEMO_QUIT, MyFrame::Menu_Exit)
64 EVT_SOCKET(SKDEMO_SOCKET_SERV, MyFrame::OnSockRequestServer)
65 EVT_SOCKET(SKDEMO_SOCKET, MyFrame::OnSockRequest)
66 END_EVENT_TABLE()
67
68 IMPLEMENT_APP(MyApp)
69
70 // `Main program' equivalent, creating windows and returning main app frame
71 bool MyApp::OnInit(void)
72 {
73 // Create the main frame window
74 MyFrame *frame = new MyFrame(NULL);
75
76 // Give it an icon
77 frame->SetIcon(wxICON(mondrian));
78
79 // Make a menubar
80 wxMenu *file_menu = new wxMenu;
81
82 file_menu->Append(SKDEMO_QUIT, "E&xit");
83 wxMenuBar *menu_bar = new wxMenuBar;
84 menu_bar->Append(file_menu, "File");
85 frame->SetMenuBar(menu_bar);
86
87 // Make a panel with a message
88 (void)new wxPanel(frame, 0, 0, 300, 100);
89
90 // Show the frame
91 frame->Show(TRUE);
92
93 // Return the main frame window
94 return TRUE;
95 }
96
97 extern wxList wxPendingDelete;
98
99 void MyFrame::OnSockRequest(wxSocketEvent& evt)
100 {
101 /* this routine gets called from within the
102 waiting socket thread, i.e. here we are
103 not in the main GUI thread and thus we
104 must not call any GUI function here. */
105 /* Wrong ! This routine is called by the main GUI thread
106 because the main GUI thread received a signal from the other
107 thread using wxEvent::ProcessThreadEvent */
108
109 wxSocketBase *sock = evt.Socket();
110
111 wxPrintf(_T("OnSockRequest OK\n"));
112 wxPrintf(_T("OnSockRequest (event = %d)\n"),evt.SocketEvent());
113 switch (evt.SocketEvent()) {
114 case wxSOCKET_INPUT:
115 unsigned char c;
116
117 sock->Read((char *)&c, 1);
118 if (c == 0xbe)
119 ExecTest1(sock);
120
121 break;
122 case wxSOCKET_LOST:
123 wxPrintf(_T("Destroying socket\n"));
124 wxPendingDelete.Append(sock);
125 UpdateStatus(-1);
126 return;
127 break;
128 default:
129 wxPrintf(_T("Invalid event !\n"));
130 }
131 wxPrintf(_T("OnSockRequest Exiting\n"));
132 }
133
134 void MyFrame::OnSockRequestServer(wxSocketEvent& evt)
135 {
136 /* this routine gets called from within the
137 waiting socket thread, i.e. here we are
138 not in the main GUI thread and thus we
139 must not call any GUI function here. */
140 /* Wrong ! This routine is called by the main GUI thread
141 because the main GUI thread received a signal from the other
142 thread using wxEvent::ProcessThreadEvent */
143
144 wxSocketBase *sock2;
145 wxSocketServer *server = (wxSocketServer *) evt.Socket();
146
147 wxPrintf(_T("OnSockRequestServer OK\n"));
148 wxPrintf(_T("OnSockRequest (Main = %d) (event = %d)\n"),wxThread::IsMain(), evt.SocketEvent());
149
150 sock2 = server->Accept();
151 if (sock2 == NULL)
152 return;
153
154 UpdateStatus(1);
155 sock2->SetFlags(wxSocketBase::NONE);
156 sock2->Notify(TRUE);
157 sock2->SetEventHandler(*this, SKDEMO_SOCKET);
158 sock2->SetNotify(wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
159 }
160
161 // My frame Constructor
162 MyFrame::MyFrame(wxFrame *frame):
163 wxFrame(frame, -1, "wxSocket sample (server)", wxDefaultPosition,
164 wxSize(300, 200))
165 {
166 wxIPV4address addr;
167 addr.Service(3000);
168
169 // Init all
170
171 sock = new wxSocketServer(addr);
172 sock->SetNotify(wxSOCKET_CONNECTION_FLAG);
173 sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV);
174 sock->SetFlags(wxSocketBase::SPEED);
175 sock->Notify(TRUE);
176 nb_clients = 0;
177
178 CreateStatusBar(1);
179 UpdateStatus(0);
180 }
181
182 MyFrame::~MyFrame()
183 {
184 delete sock;
185 }
186
187 // Intercept menu commands
188 void MyFrame::Menu_Exit(wxCommandEvent& WXUNUSED(event))
189 {
190 Close(TRUE);
191 }
192
193 void MyFrame::ExecTest1(wxSocketBase *sock_o)
194 {
195 char *buf = new char[50];
196 size_t l;
197
198 l = sock_o->Read(buf, 50).LastCount();
199 sock_o->Write(buf, l);
200 l = sock_o->Read(buf, 50).LastCount();
201 sock_o->Write(buf, l);
202
203 delete[] buf;
204 }
205
206 void MyFrame::UpdateStatus(int incr)
207 {
208 wxChar s[30];
209 nb_clients += incr;
210 wxSprintf(s, _T("%d clients connected"), nb_clients);
211 SetStatusText(s);
212 }