]> git.saurik.com Git - wxWidgets.git/blob - include/wx/private/socket.h
move Read/Write() to common code, there was almost nothing platform-specific in it
[wxWidgets.git] / include / wx / private / socket.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/private/socket.h
3 // Purpose: wxSocketImpl nd 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
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 */
53 #if !defined(__WXMAC__) && !defined(__CYGWIN__) && !defined(__WXWINCE__)
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
63 #ifdef __WXMSW__
64 #include "wx/msw/wrapwin.h"
65 #else
66 #include <sys/time.h> // for timeval
67 #endif
68
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 __WXMSW__
82 #define SOCKET int
83 #endif
84
85 #ifndef INVALID_SOCKET
86 #define INVALID_SOCKET (-1)
87 #endif
88
89 #ifndef SOCKET_ERROR
90 #define SOCKET_ERROR (-1)
91 #endif
92
93 #if wxUSE_IPV6
94 typedef struct sockaddr_storage wxSockAddr;
95 #else
96 typedef struct sockaddr wxSockAddr;
97 #endif
98
99 enum GAddressType
100 {
101 wxSOCKET_NOFAMILY = 0,
102 wxSOCKET_INET,
103 wxSOCKET_INET6,
104 wxSOCKET_UNIX
105 };
106
107 typedef int wxSocketEventFlags;
108
109 struct GAddress;
110 class wxSocketImpl;
111
112 /*
113 Class providing hooks abstracting the differences between console and GUI
114 applications for socket code.
115
116 We also have different implementations of this class for different platforms
117 allowing us to keep more things in the common code but the main reason for
118 its existence is that we want the same socket code work differently
119 depending on whether it's used from a console or a GUI program. This is
120 achieved by implementing the virtual methods of this class differently in
121 the objects returned by wxConsoleAppTraits::GetSocketManager() and the same
122 method in wxGUIAppTraits.
123 */
124 class wxSocketManager
125 {
126 public:
127 // set the manager to use, we don't take ownership of it
128 //
129 // this should be called before creating the first wxSocket object,
130 // otherwise the manager returned by wxAppTraits::GetSocketManager() will
131 // be used
132 static void Set(wxSocketManager *manager);
133
134 // return the manager to use
135 //
136 // this initializes the manager at first use
137 static wxSocketManager *Get()
138 {
139 if ( !ms_manager )
140 Init();
141
142 return ms_manager;
143 }
144
145 // called before the first wxSocket is created and should do the
146 // initializations needed in order to use the network
147 //
148 // return true if initialized successfully; if this returns false sockets
149 // can't be used at all
150 virtual bool OnInit() = 0;
151
152 // undo the initializations of OnInit()
153 virtual void OnExit() = 0;
154
155
156 // these functions enable or disable monitoring of the given socket for the
157 // specified events inside the currently running event loop (but notice
158 // that both BSD and Winsock implementations actually use socket->m_server
159 // value to determine what exactly should be monitored so it needs to be
160 // set before calling these functions)
161 virtual void Install_Callback(wxSocketImpl *socket,
162 wxSocketNotify event = wxSOCKET_MAX_EVENT) = 0;
163 virtual void Uninstall_Callback(wxSocketImpl *socket,
164 wxSocketNotify event = wxSOCKET_MAX_EVENT) = 0;
165
166 virtual ~wxSocketManager() { }
167
168 private:
169 // get the manager to use if we don't have it yet
170 static void Init();
171
172 static wxSocketManager *ms_manager;
173 };
174
175 /*
176 Base class for all socket implementations providing functionality common to
177 BSD and Winsock sockets.
178
179 Objects of this class are not created directly but only via its static
180 Create() method which is implemented in port-specific code.
181 */
182 class wxSocketImpl
183 {
184 public:
185 // static factory function: creates the low-level socket associated with
186 // the given wxSocket (and inherits its attributes such as timeout)
187 static wxSocketImpl *Create(wxSocketBase& wxsocket);
188
189 virtual ~wxSocketImpl();
190
191 // set various socket properties: all of those can only be called before
192 // creating the socket
193 void SetTimeout(unsigned long millisec);
194 void SetReusable() { m_reusable = true; }
195 void SetBroadcast() { m_broadcast = true; }
196 void DontDoBind() { m_dobind = false; }
197 void SetInitialSocketBuffers(int recv, int send)
198 {
199 m_initialRecvBufferSize = recv;
200 m_initialSendBufferSize = send;
201 }
202
203 wxSocketError SetLocal(GAddress *address);
204 wxSocketError SetPeer(GAddress *address);
205
206 // accessors
207 // ---------
208
209 bool IsServer() const { return m_server; }
210
211 GAddress *GetLocal();
212 GAddress *GetPeer();
213
214 wxSocketError GetError() const { return m_error; }
215 bool IsOk() const { return m_error == wxSOCKET_NOERROR; }
216
217 // get the error code corresponding to the last operation
218 virtual wxSocketError GetLastError() const = 0;
219
220
221 // creating/closing the socket
222 // --------------------------
223
224 // notice that SetLocal() must be called before creating the socket using
225 // any of the functions below
226 //
227 // all of Create() functions return wxSOCKET_NOERROR if the operation
228 // completed successfully or one of:
229 // wxSOCKET_INVSOCK - the socket is in use.
230 // wxSOCKET_INVADDR - the local (server) or peer (client) address has not
231 // been set.
232 // wxSOCKET_IOERR - any other error.
233
234 // create a socket listening on the local address specified by SetLocal()
235 // (notice that DontDoBind() is ignored by this function)
236 wxSocketError CreateServer();
237
238 // create a socket connected to the peer address specified by SetPeer()
239 // (notice that DontDoBind() is ignored by this function)
240 //
241 // this function may return wxSOCKET_WOULDBLOCK in addition to the return
242 // values listed above if wait is false
243 wxSocketError CreateClient(bool wait);
244
245 // create (and bind unless DontDoBind() had been called) an UDP socket
246 // associated with the given local address
247 wxSocketError CreateUDP();
248
249 // may be called whether the socket was created or not, calls DoClose() if
250 // it was indeed created
251 void Close();
252
253 // shuts down the writing end of the socket and closes it, this is a more
254 // graceful way to close
255 //
256 // does nothing if the socket wasn't created
257 void Shutdown();
258
259
260 // IO operations
261 // -------------
262
263 // basic IO, work for both TCP and UDP sockets
264 //
265 // return the number of bytes read/written (possibly 0) or -1 on error
266 int Read(void *buffer, int size);
267 int Write(const void *buffer, int size);
268
269 // basically a wrapper for select(): returns the condition of the socket,
270 // blocking for not longer than timeout if it is specified (otherwise just
271 // poll without blocking at all)
272 //
273 // flags defines what kind of conditions we're interested in, the return
274 // value is composed of a (possibly empty) subset of the bits set in flags
275 wxSocketEventFlags Select(wxSocketEventFlags flags,
276 const timeval *timeout = NULL);
277
278 // convenient wrapper calling Select() with our default timeout
279 wxSocketEventFlags SelectWithTimeout(wxSocketEventFlags flags)
280 {
281 return Select(flags, &m_timeout);
282 }
283
284 // just a wrapper for accept(): it is called to create a new wxSocketImpl
285 // corresponding to a new server connection represented by the given
286 // wxSocketBase, returns NULL on error (including immediately if there are
287 // no pending connections as our sockets are non-blocking)
288 wxSocketImpl *Accept(wxSocketBase& wxsocket);
289
290
291 // notifications
292 // -------------
293
294 // notify m_wxsocket about the given socket event by calling its (inaptly
295 // named) OnRequest() method
296 void NotifyOnStateChange(wxSocketNotify event);
297
298 // TODO: make these fields protected and provide accessors for those of
299 // them that wxSocketBase really needs
300 //protected:
301 SOCKET m_fd;
302
303 int m_initialRecvBufferSize;
304 int m_initialSendBufferSize;
305
306 GAddress *m_local;
307 GAddress *m_peer;
308 wxSocketError m_error;
309
310 bool m_stream;
311 bool m_establishing;
312 bool m_reusable;
313 bool m_broadcast;
314 bool m_dobind;
315
316 struct timeval m_timeout;
317
318 protected:
319 wxSocketImpl(wxSocketBase& wxsocket);
320
321 // true if we're a listening stream socket
322 bool m_server;
323
324 private:
325 // called by Close() if we have a valid m_fd
326 virtual void DoClose() = 0;
327
328 // put this socket into non-blocking mode and enable monitoring this socket
329 // as part of the event loop
330 virtual void UnblockAndRegisterWithEventLoop() = 0;
331
332 // check that the socket wasn't created yet and that the given address
333 // (either m_local or m_peer depending on the socket kind) is valid and
334 // set m_error and return false if this is not the case
335 bool PreCreateCheck(GAddress *addr);
336
337 // set the given socket option: this just wraps setsockopt(SOL_SOCKET)
338 int SetSocketOption(int optname, int optval)
339 {
340 // although modern Unix systems use "const void *" for the 4th
341 // parameter here, old systems and Winsock still use "const char *"
342 return setsockopt(m_fd, SOL_SOCKET, optname,
343 reinterpret_cast<const char *>(&optval),
344 sizeof(optval));
345 }
346
347 // set the given socket option to true value: this is an even simpler
348 // wrapper for setsockopt(SOL_SOCKET) for boolean options
349 int EnableSocketOption(int optname)
350 {
351 return SetSocketOption(optname, 1);
352 }
353
354 // apply the options to the (just created) socket and register it with the
355 // event loop by calling UnblockAndRegisterWithEventLoop()
356 void PostCreation();
357
358 // update local address after binding/connecting
359 wxSocketError UpdateLocalAddress();
360
361 // functions used to implement Read/Write()
362 int RecvStream(void *buffer, int size);
363 int RecvDgram(void *buffer, int size);
364 int SendStream(const void *buffer, int size);
365 int SendDgram(const void *buffer, int size);
366
367
368 // set in ctor and never changed except that it's reset to NULL when the
369 // socket is shut down
370 wxSocketBase *m_wxsocket;
371
372 DECLARE_NO_COPY_CLASS(wxSocketImpl)
373 };
374
375 #if defined(__WXMSW__)
376 #include "wx/msw/private/sockmsw.h"
377 #else
378 #include "wx/unix/private/sockunix.h"
379 #endif
380
381
382 /* GAddress */
383
384 // TODO: make GAddress a real class instead of this mix of C and C++
385
386 // Represents a socket endpoint, i.e. -- in spite of its name -- not an address
387 // but an (address, port) pair
388 struct GAddress
389 {
390 struct sockaddr *m_addr;
391 size_t m_len;
392
393 GAddressType m_family;
394 int m_realfamily;
395
396 wxSocketError m_error;
397 };
398
399 GAddress *GAddress_new();
400 GAddress *GAddress_copy(GAddress *address);
401 void GAddress_destroy(GAddress *address);
402
403 void GAddress_SetFamily(GAddress *address, GAddressType type);
404 GAddressType GAddress_GetFamily(GAddress *address);
405
406 /* The use of any of the next functions will set the address family to
407 * the specific one. For example if you use GAddress_INET_SetHostName,
408 * address family will be implicitly set to AF_INET.
409 */
410
411 wxSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname);
412 wxSocketError GAddress_INET_SetBroadcastAddress(GAddress *address);
413 wxSocketError GAddress_INET_SetAnyAddress(GAddress *address);
414 wxSocketError GAddress_INET_SetHostAddress(GAddress *address,
415 unsigned long hostaddr);
416 wxSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
417 const char *protocol);
418 wxSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port);
419
420 wxSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname,
421 size_t sbuf);
422 unsigned long GAddress_INET_GetHostAddress(GAddress *address);
423 unsigned short GAddress_INET_GetPort(GAddress *address);
424
425 wxSocketError _GAddress_translate_from(GAddress *address,
426 struct sockaddr *addr, int len);
427 wxSocketError _GAddress_translate_to (GAddress *address,
428 struct sockaddr **addr, int *len);
429 wxSocketError _GAddress_Init_INET(GAddress *address);
430
431 #if wxUSE_IPV6
432
433 wxSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname);
434 wxSocketError GAddress_INET6_SetAnyAddress(GAddress *address);
435 wxSocketError GAddress_INET6_SetHostAddress(GAddress *address,
436 struct in6_addr hostaddr);
437 wxSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
438 const char *protocol);
439 wxSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port);
440
441 wxSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname,
442 size_t sbuf);
443 wxSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr);
444 unsigned short GAddress_INET6_GetPort(GAddress *address);
445
446 #endif // wxUSE_IPV6
447
448 // these functions are available under all platforms but only implemented under
449 // Unix ones, elsewhere they just return wxSOCKET_INVADDR
450 wxSocketError _GAddress_Init_UNIX(GAddress *address);
451 wxSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
452 wxSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
453
454 #endif /* wxUSE_SOCKETS */
455
456 #endif /* _WX_PRIVATE_SOCKET_H_ */