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