]>
Commit | Line | Data |
---|---|---|
f4ada568 GL |
1 | /* |
2 | * File: server.cpp | |
3 | * Purpose: wxSocket: server 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 | |
f4ada568 | 26 | #include "wx/socket.h" |
6b3eb77a | 27 | #include "wx/thread.h" |
f4ada568 | 28 | |
e2a6f233 JS |
29 | #if defined(__WXMOTIF__) || defined(__WXGTK__) |
30 | #include "mondrian.xpm" | |
31 | #endif | |
32 | ||
f4ada568 GL |
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: | |
a737331d | 46 | wxSocketServer *sock; |
f4ada568 GL |
47 | int nb_clients; |
48 | ||
49 | MyFrame(wxFrame *frame); | |
50 | virtual ~MyFrame(); | |
51 | void Menu_Exit(wxCommandEvent& evt); | |
a737331d GL |
52 | void OnSockRequest(wxSocketEvent& evt); |
53 | void OnSockRequestServer(wxSocketEvent& evt); | |
f4ada568 GL |
54 | void ExecTest1(wxSocketBase *sock_o); |
55 | void UpdateStatus(int incr); | |
56 | }; | |
57 | ||
58 | #define SKDEMO_QUIT 101 | |
a737331d GL |
59 | #define SKDEMO_SOCKET_SERV 102 |
60 | #define SKDEMO_SOCKET 103 | |
f4ada568 GL |
61 | |
62 | BEGIN_EVENT_TABLE(MyFrame, wxFrame) | |
63 | EVT_MENU(SKDEMO_QUIT, MyFrame::Menu_Exit) | |
a737331d GL |
64 | EVT_SOCKET(SKDEMO_SOCKET_SERV, MyFrame::OnSockRequestServer) |
65 | EVT_SOCKET(SKDEMO_SOCKET, MyFrame::OnSockRequest) | |
f4ada568 GL |
66 | END_EVENT_TABLE() |
67 | ||
f4ada568 GL |
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 | |
e2a6f233 | 77 | frame->SetIcon(wxICON(mondrian)); |
f4ada568 GL |
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 | ||
a737331d GL |
97 | extern wxList wxPendingDelete; |
98 | ||
99 | void MyFrame::OnSockRequest(wxSocketEvent& evt) | |
f4ada568 | 100 | { |
6b3eb77a RR |
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. */ | |
062c4861 GL |
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 */ | |
6b3eb77a | 108 | |
a737331d | 109 | wxSocketBase *sock = evt.Socket(); |
f4ada568 | 110 | |
a737331d GL |
111 | printf("OnSockRequest OK\n"); |
112 | printf("OnSockRequest (event = %d)\n",evt.SocketEvent()); | |
113 | switch (evt.SocketEvent()) { | |
114 | case wxSocketBase::EVT_READ: | |
f4ada568 GL |
115 | unsigned char c; |
116 | ||
a737331d | 117 | sock->Read((char *)&c, 1); |
f4ada568 | 118 | if (c == 0xbe) |
a737331d | 119 | ExecTest1(sock); |
f4ada568 GL |
120 | |
121 | break; | |
a737331d | 122 | case wxSocketBase::EVT_LOST: |
a737331d GL |
123 | printf("Destroying socket\n"); |
124 | wxPendingDelete.Append(sock); | |
062c4861 | 125 | UpdateStatus(-1); |
a737331d | 126 | return; |
f4ada568 GL |
127 | break; |
128 | } | |
a737331d GL |
129 | printf("OnSockRequest Exiting\n"); |
130 | sock->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST); | |
f4ada568 GL |
131 | } |
132 | ||
a737331d | 133 | void MyFrame::OnSockRequestServer(wxSocketEvent& evt) |
f4ada568 | 134 | { |
6b3eb77a RR |
135 | /* this routine gets called from within the |
136 | waiting socket thread, i.e. here we are | |
137 | not in the main GUI thread and thus we | |
138 | must not call any GUI function here. */ | |
062c4861 GL |
139 | /* Wrong ! This routine is called by the main GUI thread |
140 | because the main GUI thread received a signal from the other | |
141 | thread using wxEvent::ProcessThreadEvent */ | |
6b3eb77a | 142 | |
a737331d GL |
143 | wxSocketBase *sock2; |
144 | wxSocketServer *server = (wxSocketServer *) evt.Socket(); | |
f4ada568 | 145 | |
a737331d | 146 | printf("OnSockRequestServer OK\n"); |
062c4861 | 147 | printf("OnSockRequest (Main = %d) (event = %d)\n",wxThread::IsMain(), evt.SocketEvent()); |
f4ada568 | 148 | |
a737331d GL |
149 | sock2 = server->Accept(); |
150 | if (sock2 == NULL) | |
151 | return; | |
f4ada568 | 152 | |
062c4861 | 153 | UpdateStatus(1); |
9111db68 | 154 | sock2->SetFlags(wxSocketBase::SPEED); |
f4ada568 | 155 | sock2->Notify(TRUE); |
a737331d GL |
156 | sock2->SetEventHandler(*this, SKDEMO_SOCKET); |
157 | server->SetNotify(wxSocketBase::REQ_ACCEPT); | |
f4ada568 GL |
158 | } |
159 | ||
160 | // My frame Constructor | |
161 | MyFrame::MyFrame(wxFrame *frame): | |
162 | wxFrame(frame, -1, "wxSocket sample (server)", wxDefaultPosition, | |
163 | wxSize(300, 200)) | |
164 | { | |
165 | wxIPV4address addr; | |
166 | addr.Service(3000); | |
167 | ||
168 | // Init all | |
169 | wxSocketHandler::Master(); | |
170 | ||
a737331d | 171 | sock = new wxSocketServer(addr); |
f4ada568 | 172 | wxSocketHandler::Master().Register(sock); |
f4ada568 | 173 | sock->SetNotify(wxSocketBase::REQ_ACCEPT); |
a737331d | 174 | sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV); |
9111db68 | 175 | sock->SetFlags(wxSocketBase::SPEED); |
f4ada568 GL |
176 | sock->Notify(TRUE); |
177 | nb_clients = 0; | |
178 | ||
179 | CreateStatusBar(1); | |
180 | UpdateStatus(0); | |
181 | } | |
182 | ||
183 | MyFrame::~MyFrame() | |
184 | { | |
185 | delete sock; | |
186 | } | |
187 | ||
188 | // Intercept menu commands | |
d18ed59a | 189 | void MyFrame::Menu_Exit(wxCommandEvent& WXUNUSED(event)) |
f4ada568 GL |
190 | { |
191 | Close(TRUE); | |
192 | } | |
193 | ||
194 | void MyFrame::ExecTest1(wxSocketBase *sock_o) | |
195 | { | |
196 | char *buf = new char[50]; | |
197 | size_t l; | |
198 | ||
199 | l = sock_o->Read(buf, 50).LastCount(); | |
200 | sock_o->Write(buf, l); | |
201 | } | |
202 | ||
203 | void MyFrame::UpdateStatus(int incr) | |
204 | { | |
205 | char s[30]; | |
206 | nb_clients += incr; | |
207 | sprintf(s, "%d clients connected", nb_clients); | |
208 | SetStatusText(s); | |
209 | } |