]> git.saurik.com Git - wxWidgets.git/blame - include/wx/private/socket.h
move enabled callbacks flag down to wxSocketImplUnix from wxSocketImplFDIO, this...
[wxWidgets.git] / include / wx / private / socket.h
CommitLineData
60913641 1/////////////////////////////////////////////////////////////////////////////
02564412 2// Name: wx/private/socket.h
60913641
VZ
3// Purpose: wxSocketImpl nd related declarations
4// Authors: Guilhem Lavaux, Vadim Zeitlin
5// Created: April 1997
a9d859df 6// RCS-ID: $Id: socket.h 56994 2008-11-28 12:47:07Z VZ $
60913641
VZ
7// Copyright: (c) 1997 Guilhem Lavaux
8// (c) 2008 Vadim Zeitlin
02564412 9// Licence: wxWindows licence
60913641
VZ
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 wxSocketManager::CreateSocket().
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 */
02564412
VZ
36
37#ifndef _WX_PRIVATE_SOCKET_H_
38#define _WX_PRIVATE_SOCKET_H_
39
60913641
VZ
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
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
60913641
VZ
81#ifndef SOCKET
82 #define SOCKET int
83#endif
84
02564412
VZ
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
60913641
VZ
99enum GAddressType
100{
101 wxSOCKET_NOFAMILY = 0,
102 wxSOCKET_INET,
103 wxSOCKET_INET6,
104 wxSOCKET_UNIX
105};
106
107typedef int wxSocketEventFlags;
108
109struct GAddress;
110class 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 */
124class wxSocketManager
125{
126public:
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 // create a concrete socket implementation associated with the given
157 // wxSocket object
158 //
159 // the returned object must be deleted by the caller
160 virtual wxSocketImpl *CreateSocket(wxSocketBase& wxsocket) = 0;
161
162
163
164 // these functions enable or disable monitoring of the given socket for the
165 // specified events inside the currently running event loop (but notice
166 // that both BSD and Winsock implementations actually use socket->m_server
167 // value to determine what exactly should be monitored so it needs to be
168 // set before calling these functions)
169 virtual void Install_Callback(wxSocketImpl *socket,
170 wxSocketNotify event = wxSOCKET_MAX_EVENT) = 0;
171 virtual void Uninstall_Callback(wxSocketImpl *socket,
172 wxSocketNotify event = wxSOCKET_MAX_EVENT) = 0;
173
174 virtual ~wxSocketManager() { }
175
176private:
177 // get the manager to use if we don't have it yet
178 static void Init();
179
180 static wxSocketManager *ms_manager;
181};
182
183/*
184 Base class for all socket implementations providing functionality common to
185 BSD and Winsock sockets.
186
187 Objects of this class are not created directly but only via its static
188 Create() method which in turn forwards to wxSocketManager::CreateSocket().
189 */
190class wxSocketImpl
191{
192public:
193 // static factory function: creates the low-level socket associated with
194 // the given wxSocket (and inherits its attributes such as timeout)
195 static wxSocketImpl *Create(wxSocketBase& wxsocket);
196
197 virtual ~wxSocketImpl();
198
199 // set various socket properties: all of those can only be called before
200 // creating the socket
201 void SetTimeout(unsigned long millisec);
202 void SetNonBlocking(bool non_blocking) { m_non_blocking = non_blocking; }
203 void SetReusable() { m_reusable = true; }
204 void SetBroadcast() { m_broadcast = true; }
205 void DontDoBind() { m_dobind = false; }
206 void SetInitialSocketBuffers(int recv, int send)
207 {
208 m_initialRecvBufferSize = recv;
209 m_initialSendBufferSize = send;
210 }
211
212 wxSocketError SetLocal(GAddress *address);
213 wxSocketError SetPeer(GAddress *address);
214
215 // accessors
216 // ---------
217
218 GAddress *GetLocal();
219 GAddress *GetPeer();
220
221 wxSocketError GetError() const { return m_error; }
222 bool IsOk() const { return m_error == wxSOCKET_NOERROR; }
223
224
225 // creating/closing the socket
226 // --------------------------
227
228 // notice that SetLocal() must be called before creating the socket using
229 // any of the functions below
230 //
231 // all of Create() functions return wxSOCKET_NOERROR if the operation
232 // completed successfully or one of:
233 // wxSOCKET_INVSOCK - the socket is in use.
234 // wxSOCKET_INVADDR - the local (server) or peer (client) address has not
235 // been set.
236 // wxSOCKET_IOERR - any other error.
237
238 // create a socket listening on the local address specified by SetLocal()
239 // (notice that DontDoBind() is ignored by this function)
240 wxSocketError CreateServer();
241
242 // create a socket connected to the peer address specified by SetPeer()
243 // (notice that DontDoBind() is ignored by this function)
244 //
245 // this function may return wxSOCKET_WOULDBLOCK in addition to the return
246 // values listed above
247 wxSocketError CreateClient();
248
249 // create (and bind unless DontDoBind() had been called) an UDP socket
250 // associated with the given local address
251 wxSocketError CreateUDP();
252
253 // may be called whether the socket was created or not, calls DoClose() if
254 // it was indeed created
255 void Close();
256
257 virtual void Shutdown();
258
259
260 // IO operations
261 // -------------
262
263 virtual int Read(char *buffer, int size) = 0;
264 virtual int Write(const char *buffer, int size) = 0;
265
266 wxSocketEventFlags Select(wxSocketEventFlags flags);
267
268 virtual wxSocketImpl *WaitConnection(wxSocketBase& wxsocket) = 0;
269
270
271 // notifications
272 // -------------
273
274 // notify m_wxsocket about the given socket event by calling its (inaptly
275 // named) OnRequest() method
276 void NotifyOnStateChange(wxSocketNotify event);
277
a9d859df 278 // FIXME: this one probably isn't needed here at all
60913641
VZ
279 virtual void Notify(bool WXUNUSED(notify)) { }
280
281 // TODO: make these fields protected and provide accessors for those of
282 // them that wxSocketBase really needs
283//protected:
284 SOCKET m_fd;
285
286 int m_initialRecvBufferSize;
287 int m_initialSendBufferSize;
288
289 GAddress *m_local;
290 GAddress *m_peer;
291 wxSocketError m_error;
292
293 bool m_non_blocking;
294 bool m_server;
295 bool m_stream;
296 bool m_establishing;
297 bool m_reusable;
298 bool m_broadcast;
299 bool m_dobind;
300
301 struct timeval m_timeout;
302
303 wxSocketEventFlags m_detected;
304
305protected:
306 wxSocketImpl(wxSocketBase& wxsocket);
307
308private:
309 // handle the given connect() return value (which may be 0 or EWOULDBLOCK
310 // or something else)
311 virtual wxSocketError DoHandleConnect(int ret) = 0;
312
313 // called by Close() if we have a valid m_fd
314 virtual void DoClose() = 0;
315
316 // put this socket into non-blocking mode and enable monitoring this socket
317 // as part of the event loop
318 virtual void UnblockAndRegisterWithEventLoop() = 0;
319
320 // check that the socket wasn't created yet and that the given address
321 // (either m_local or m_peer depending on the socket kind) is valid and
322 // set m_error and return false if this is not the case
323 bool PreCreateCheck(GAddress *addr);
324
325 // set the given socket option: this just wraps setsockopt(SOL_SOCKET)
326 int SetSocketOption(int optname, int optval)
327 {
328 // although modern Unix systems use "const void *" for the 4th
329 // parameter here, old systems and Winsock still use "const char *"
330 return setsockopt(m_fd, SOL_SOCKET, optname,
331 reinterpret_cast<const char *>(&optval),
332 sizeof(optval));
333 }
334
335 // set the given socket option to true value: this is an even simpler
336 // wrapper for setsockopt(SOL_SOCKET) for boolean options
337 int EnableSocketOption(int optname)
338 {
339 return SetSocketOption(optname, 1);
340 }
341
342 // apply the options to the (just created) socket and register it with the
343 // event loop by calling UnblockAndRegisterWithEventLoop()
344 void PostCreation();
345
346 // update local address after binding/connecting
347 wxSocketError UpdateLocalAddress();
348
349
350 // set in ctor and never changed except that it's reset to NULL when the
351 // socket is shut down
352 wxSocketBase *m_wxsocket;
353
354 DECLARE_NO_COPY_CLASS(wxSocketImpl)
355};
356
357#if defined(__WXMSW__)
358 #include "wx/msw/gsockmsw.h"
359#else
360 #include "wx/unix/private/sockunix.h"
361#endif
362
363
364/* GAddress */
365
366// TODO: make GAddress a real class instead of this mix of C and C++
367
368// Represents a socket endpoint, i.e. -- in spite of its name -- not an address
369// but an (address, port) pair
370struct GAddress
371{
372 struct sockaddr *m_addr;
373 size_t m_len;
374
375 GAddressType m_family;
376 int m_realfamily;
377
378 wxSocketError m_error;
379};
380
381GAddress *GAddress_new();
382GAddress *GAddress_copy(GAddress *address);
383void GAddress_destroy(GAddress *address);
384
385void GAddress_SetFamily(GAddress *address, GAddressType type);
386GAddressType GAddress_GetFamily(GAddress *address);
387
388/* The use of any of the next functions will set the address family to
389 * the specific one. For example if you use GAddress_INET_SetHostName,
390 * address family will be implicitly set to AF_INET.
391 */
392
393wxSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname);
394wxSocketError GAddress_INET_SetBroadcastAddress(GAddress *address);
395wxSocketError GAddress_INET_SetAnyAddress(GAddress *address);
396wxSocketError GAddress_INET_SetHostAddress(GAddress *address,
397 unsigned long hostaddr);
398wxSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
399 const char *protocol);
400wxSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port);
401
402wxSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname,
403 size_t sbuf);
404unsigned long GAddress_INET_GetHostAddress(GAddress *address);
405unsigned short GAddress_INET_GetPort(GAddress *address);
406
407wxSocketError _GAddress_translate_from(GAddress *address,
408 struct sockaddr *addr, int len);
409wxSocketError _GAddress_translate_to (GAddress *address,
410 struct sockaddr **addr, int *len);
411wxSocketError _GAddress_Init_INET(GAddress *address);
412
413#if wxUSE_IPV6
414
415wxSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname);
416wxSocketError GAddress_INET6_SetAnyAddress(GAddress *address);
417wxSocketError GAddress_INET6_SetHostAddress(GAddress *address,
418 struct in6_addr hostaddr);
419wxSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
420 const char *protocol);
421wxSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port);
422
423wxSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname,
424 size_t sbuf);
425wxSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr);
426unsigned short GAddress_INET6_GetPort(GAddress *address);
427
428#endif // wxUSE_IPV6
429
430// these functions are available under all platforms but only implemented under
431// Unix ones, elsewhere they just return wxSOCKET_INVADDR
432wxSocketError _GAddress_Init_UNIX(GAddress *address);
433wxSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
434wxSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
435
436#endif /* wxUSE_SOCKETS */
02564412 437
60913641 438#endif /* _WX_PRIVATE_SOCKET_H_ */