]> git.saurik.com Git - wxWidgets.git/blame - include/wx/private/socket.h
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / include / wx / private / socket.h
CommitLineData
60913641 1/////////////////////////////////////////////////////////////////////////////
02564412 2// Name: wx/private/socket.h
87315ea2 3// Purpose: wxSocketImpl and related declarations
60913641
VZ
4// Authors: Guilhem Lavaux, Vadim Zeitlin
5// Created: April 1997
60913641
VZ
6// Copyright: (c) 1997 Guilhem Lavaux
7// (c) 2008 Vadim Zeitlin
02564412 8// Licence: wxWindows licence
60913641
VZ
9/////////////////////////////////////////////////////////////////////////////
10
11/*
12 Brief overview of different socket classes:
13
14 - wxSocketBase is the public class representing a socket ("Base" here
15 refers to the fact that wxSocketClient and wxSocketServer are derived
16 from it and predates the convention of using "Base" for common base
17 classes for platform-specific classes in wxWidgets) with implementation
18 common to all platforms and forwarding methods whose implementation
19 differs between platforms to wxSocketImpl which it contains.
20
21 - wxSocketImpl is actually just an abstract base class having only code
22 common to all platforms, the concrete implementation classes derive from
54cb21d6 23 it and are created by wxSocketImpl::Create().
60913641
VZ
24
25 - Some socket operations have different implementations in console-mode and
26 GUI applications. wxSocketManager class exists to abstract this in such
27 way that console applications (using wxBase) don't depend on wxNet. An
28 object of this class is made available via wxApp and GUI applications set
29 up a different kind of global socket manager from console ones.
30
31 TODO: it looks like wxSocketManager could be eliminated by providing
32 methods for registering/unregistering sockets directly in
33 wxEventLoop.
34 */
02564412
VZ
35
36#ifndef _WX_PRIVATE_SOCKET_H_
37#define _WX_PRIVATE_SOCKET_H_
38
60913641
VZ
39#include "wx/defs.h"
40
41#if wxUSE_SOCKETS
42
43#include "wx/socket.h"
c9bccf23 44#include "wx/private/sckaddr.h"
60913641
VZ
45
46#include <stddef.h>
47
48/*
49 Including sys/types.h under Cygwin results in the warnings about "fd_set
50 having been defined in sys/types.h" when winsock.h is included later and
51 doesn't seem to be necessary anyhow. It's not needed under Mac neither.
52 */
acbed114 53#if !defined(__WXMAC__) && !defined(__WXMSW__) && !defined(__WXWINCE__)
60913641
VZ
54#include <sys/types.h>
55#endif
56
57#ifdef __WXWINCE__
58#include <stdlib.h>
59#endif
60
61// include the header defining timeval: under Windows this struct is used only
62// with sockets so we need to include winsock.h which we do via windows.h
d98a58c5 63#ifdef __WINDOWS__
60913641
VZ
64 #include "wx/msw/wrapwin.h"
65#else
66 #include <sys/time.h> // for timeval
67#endif
68
02564412
VZ
69// these definitions are for MSW when we don't use configure, otherwise these
70// symbols are defined by configure
71#ifndef WX_SOCKLEN_T
72 #define WX_SOCKLEN_T int
73#endif
74
75#ifndef SOCKOPTLEN_T
76 #define SOCKOPTLEN_T int
77#endif
78
79// define some symbols which winsock.h defines but traditional BSD headers
80// don't
81#ifndef INVALID_SOCKET
82 #define INVALID_SOCKET (-1)
83#endif
84
85#ifndef SOCKET_ERROR
86 #define SOCKET_ERROR (-1)
87#endif
88
60913641
VZ
89typedef int wxSocketEventFlags;
90
60913641
VZ
91class wxSocketImpl;
92
93/*
94 Class providing hooks abstracting the differences between console and GUI
95 applications for socket code.
96
97 We also have different implementations of this class for different platforms
98 allowing us to keep more things in the common code but the main reason for
99 its existence is that we want the same socket code work differently
100 depending on whether it's used from a console or a GUI program. This is
101 achieved by implementing the virtual methods of this class differently in
102 the objects returned by wxConsoleAppTraits::GetSocketManager() and the same
103 method in wxGUIAppTraits.
104 */
105class wxSocketManager
106{
107public:
108 // set the manager to use, we don't take ownership of it
109 //
110 // this should be called before creating the first wxSocket object,
111 // otherwise the manager returned by wxAppTraits::GetSocketManager() will
112 // be used
113 static void Set(wxSocketManager *manager);
114
115 // return the manager to use
116 //
117 // this initializes the manager at first use
118 static wxSocketManager *Get()
119 {
120 if ( !ms_manager )
121 Init();
122
123 return ms_manager;
124 }
125
126 // called before the first wxSocket is created and should do the
127 // initializations needed in order to use the network
128 //
129 // return true if initialized successfully; if this returns false sockets
130 // can't be used at all
131 virtual bool OnInit() = 0;
132
133 // undo the initializations of OnInit()
134 virtual void OnExit() = 0;
135
136
4f260c9c
VZ
137 // create the socket implementation object matching this manager
138 virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket) = 0;
139
60913641
VZ
140 // these functions enable or disable monitoring of the given socket for the
141 // specified events inside the currently running event loop (but notice
142 // that both BSD and Winsock implementations actually use socket->m_server
143 // value to determine what exactly should be monitored so it needs to be
144 // set before calling these functions)
c363ead1
VZ
145 //
146 // the default event value is used just for the convenience of wxMSW
147 // implementation which doesn't use this parameter anyhow, it doesn't make
148 // sense to pass wxSOCKET_LOST for the Unix implementation which does use
149 // this parameter
60913641 150 virtual void Install_Callback(wxSocketImpl *socket,
c363ead1 151 wxSocketNotify event = wxSOCKET_LOST) = 0;
60913641 152 virtual void Uninstall_Callback(wxSocketImpl *socket,
c363ead1 153 wxSocketNotify event = wxSOCKET_LOST) = 0;
60913641
VZ
154
155 virtual ~wxSocketManager() { }
156
157private:
158 // get the manager to use if we don't have it yet
159 static void Init();
160
161 static wxSocketManager *ms_manager;
162};
163
164/*
165 Base class for all socket implementations providing functionality common to
166 BSD and Winsock sockets.
167
4f260c9c
VZ
168 Objects of this class are not created directly but only via the factory
169 function wxSocketManager::CreateSocket().
60913641
VZ
170 */
171class wxSocketImpl
172{
173public:
60913641
VZ
174 virtual ~wxSocketImpl();
175
176 // set various socket properties: all of those can only be called before
177 // creating the socket
178 void SetTimeout(unsigned long millisec);
60913641
VZ
179 void SetReusable() { m_reusable = true; }
180 void SetBroadcast() { m_broadcast = true; }
181 void DontDoBind() { m_dobind = false; }
182 void SetInitialSocketBuffers(int recv, int send)
183 {
184 m_initialRecvBufferSize = recv;
185 m_initialSendBufferSize = send;
186 }
187
c9bccf23
VZ
188 wxSocketError SetLocal(const wxSockAddressImpl& address);
189 wxSocketError SetPeer(const wxSockAddressImpl& address);
60913641
VZ
190
191 // accessors
192 // ---------
193
2b036c4b
VZ
194 bool IsServer() const { return m_server; }
195
c9bccf23
VZ
196 const wxSockAddressImpl& GetLocal(); // non const as may update m_local
197 const wxSockAddressImpl& GetPeer() const { return m_peer; }
60913641
VZ
198
199 wxSocketError GetError() const { return m_error; }
200 bool IsOk() const { return m_error == wxSOCKET_NOERROR; }
201
2b036c4b
VZ
202 // get the error code corresponding to the last operation
203 virtual wxSocketError GetLastError() const = 0;
204
60913641
VZ
205
206 // creating/closing the socket
207 // --------------------------
208
209 // notice that SetLocal() must be called before creating the socket using
210 // any of the functions below
211 //
212 // all of Create() functions return wxSOCKET_NOERROR if the operation
213 // completed successfully or one of:
214 // wxSOCKET_INVSOCK - the socket is in use.
215 // wxSOCKET_INVADDR - the local (server) or peer (client) address has not
216 // been set.
217 // wxSOCKET_IOERR - any other error.
218
219 // create a socket listening on the local address specified by SetLocal()
220 // (notice that DontDoBind() is ignored by this function)
221 wxSocketError CreateServer();
222
223 // create a socket connected to the peer address specified by SetPeer()
224 // (notice that DontDoBind() is ignored by this function)
225 //
226 // this function may return wxSOCKET_WOULDBLOCK in addition to the return
2b036c4b
VZ
227 // values listed above if wait is false
228 wxSocketError CreateClient(bool wait);
60913641
VZ
229
230 // create (and bind unless DontDoBind() had been called) an UDP socket
231 // associated with the given local address
232 wxSocketError CreateUDP();
233
234 // may be called whether the socket was created or not, calls DoClose() if
235 // it was indeed created
236 void Close();
237
62088a3c
VZ
238 // shuts down the writing end of the socket and closes it, this is a more
239 // graceful way to close
240 //
241 // does nothing if the socket wasn't created
242 void Shutdown();
60913641
VZ
243
244
245 // IO operations
246 // -------------
247
14372de8
VZ
248 // basic IO, work for both TCP and UDP sockets
249 //
250 // return the number of bytes read/written (possibly 0) or -1 on error
251 int Read(void *buffer, int size);
252 int Write(const void *buffer, int size);
60913641 253
00414faf 254 // basically a wrapper for select(): returns the condition of the socket,
2b036c4b
VZ
255 // blocking for not longer than timeout if it is specified (otherwise just
256 // poll without blocking at all)
00414faf
VZ
257 //
258 // flags defines what kind of conditions we're interested in, the return
259 // value is composed of a (possibly empty) subset of the bits set in flags
260 wxSocketEventFlags Select(wxSocketEventFlags flags,
2b036c4b
VZ
261 const timeval *timeout = NULL);
262
263 // convenient wrapper calling Select() with our default timeout
264 wxSocketEventFlags SelectWithTimeout(wxSocketEventFlags flags)
265 {
266 return Select(flags, &m_timeout);
267 }
60913641 268
2b036c4b
VZ
269 // just a wrapper for accept(): it is called to create a new wxSocketImpl
270 // corresponding to a new server connection represented by the given
271 // wxSocketBase, returns NULL on error (including immediately if there are
272 // no pending connections as our sockets are non-blocking)
273 wxSocketImpl *Accept(wxSocketBase& wxsocket);
60913641
VZ
274
275
276 // notifications
277 // -------------
278
279 // notify m_wxsocket about the given socket event by calling its (inaptly
280 // named) OnRequest() method
281 void NotifyOnStateChange(wxSocketNotify event);
282
df21920b
VZ
283 // called after reading/writing the data from/to the socket and should
284 // enable back the wxSOCKET_INPUT/OUTPUT_FLAG notifications if they were
285 // turned off when this data was first detected
286 virtual void ReenableEvents(wxSocketEventFlags flags) = 0;
287
60913641
VZ
288 // TODO: make these fields protected and provide accessors for those of
289 // them that wxSocketBase really needs
290//protected:
0623b0f0 291 wxSOCKET_T m_fd;
60913641
VZ
292
293 int m_initialRecvBufferSize;
294 int m_initialSendBufferSize;
295
c9bccf23
VZ
296 wxSockAddressImpl m_local,
297 m_peer;
60913641
VZ
298 wxSocketError m_error;
299
60913641
VZ
300 bool m_stream;
301 bool m_establishing;
302 bool m_reusable;
303 bool m_broadcast;
304 bool m_dobind;
305
306 struct timeval m_timeout;
307
60913641
VZ
308protected:
309 wxSocketImpl(wxSocketBase& wxsocket);
310
2b036c4b
VZ
311 // true if we're a listening stream socket
312 bool m_server;
c6b10632 313
60913641 314private:
60913641
VZ
315 // called by Close() if we have a valid m_fd
316 virtual void DoClose() = 0;
317
318 // put this socket into non-blocking mode and enable monitoring this socket
319 // as part of the event loop
320 virtual void UnblockAndRegisterWithEventLoop() = 0;
321
322 // check that the socket wasn't created yet and that the given address
323 // (either m_local or m_peer depending on the socket kind) is valid and
324 // set m_error and return false if this is not the case
c9bccf23 325 bool PreCreateCheck(const wxSockAddressImpl& addr);
60913641
VZ
326
327 // set the given socket option: this just wraps setsockopt(SOL_SOCKET)
328 int SetSocketOption(int optname, int optval)
329 {
330 // although modern Unix systems use "const void *" for the 4th
331 // parameter here, old systems and Winsock still use "const char *"
332 return setsockopt(m_fd, SOL_SOCKET, optname,
333 reinterpret_cast<const char *>(&optval),
334 sizeof(optval));
335 }
336
337 // set the given socket option to true value: this is an even simpler
338 // wrapper for setsockopt(SOL_SOCKET) for boolean options
339 int EnableSocketOption(int optname)
340 {
341 return SetSocketOption(optname, 1);
342 }
343
344 // apply the options to the (just created) socket and register it with the
345 // event loop by calling UnblockAndRegisterWithEventLoop()
346 void PostCreation();
347
348 // update local address after binding/connecting
349 wxSocketError UpdateLocalAddress();
350
14372de8
VZ
351 // functions used to implement Read/Write()
352 int RecvStream(void *buffer, int size);
353 int RecvDgram(void *buffer, int size);
354 int SendStream(const void *buffer, int size);
355 int SendDgram(const void *buffer, int size);
356
60913641
VZ
357
358 // set in ctor and never changed except that it's reset to NULL when the
359 // socket is shut down
360 wxSocketBase *m_wxsocket;
361
c0c133e1 362 wxDECLARE_NO_COPY_CLASS(wxSocketImpl);
60913641
VZ
363};
364
d98a58c5 365#if defined(__WINDOWS__)
26067161 366 #include "wx/msw/private/sockmsw.h"
60913641
VZ
367#else
368 #include "wx/unix/private/sockunix.h"
369#endif
370
60913641 371#endif /* wxUSE_SOCKETS */
02564412 372
60913641 373#endif /* _WX_PRIVATE_SOCKET_H_ */