1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/private/socket.h
3 // Purpose: wxSocketImpl nd related declarations
4 // Authors: Guilhem Lavaux, Vadim Zeitlin
7 // Copyright: (c) 1997 Guilhem Lavaux
8 // (c) 2008 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 Brief overview of different socket classes:
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.
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().
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.
32 TODO: it looks like wxSocketManager could be eliminated by providing
33 methods for registering/unregistering sockets directly in
37 #ifndef _WX_PRIVATE_SOCKET_H_
38 #define _WX_PRIVATE_SOCKET_H_
44 #include "wx/socket.h"
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.
53 #if !defined(__WXMAC__) && !defined(__CYGWIN__) && !defined(__WXWINCE__)
54 #include <sys/types.h>
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
64 #include "wx/msw/wrapwin.h"
66 #include <sys/time.h> // for timeval
69 // these definitions are for MSW when we don't use configure, otherwise these
70 // symbols are defined by configure
72 #define WX_SOCKLEN_T int
76 #define SOCKOPTLEN_T int
79 // define some symbols which winsock.h defines but traditional BSD headers
85 #ifndef INVALID_SOCKET
86 #define INVALID_SOCKET (-1)
90 #define SOCKET_ERROR (-1)
94 typedef struct sockaddr_storage wxSockAddr
;
96 typedef struct sockaddr wxSockAddr
;
101 wxSOCKET_NOFAMILY
= 0,
107 typedef int wxSocketEventFlags
;
113 Class providing hooks abstracting the differences between console and GUI
114 applications for socket code.
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.
124 class wxSocketManager
127 // set the manager to use, we don't take ownership of it
129 // this should be called before creating the first wxSocket object,
130 // otherwise the manager returned by wxAppTraits::GetSocketManager() will
132 static void Set(wxSocketManager
*manager
);
134 // return the manager to use
136 // this initializes the manager at first use
137 static wxSocketManager
*Get()
145 // called before the first wxSocket is created and should do the
146 // initializations needed in order to use the network
148 // return true if initialized successfully; if this returns false sockets
149 // can't be used at all
150 virtual bool OnInit() = 0;
152 // undo the initializations of OnInit()
153 virtual void OnExit() = 0;
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;
166 virtual ~wxSocketManager() { }
169 // get the manager to use if we don't have it yet
172 static wxSocketManager
*ms_manager
;
176 Base class for all socket implementations providing functionality common to
177 BSD and Winsock sockets.
179 Objects of this class are not created directly but only via its static
180 Create() method which is implemented in port-specific code.
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
);
189 virtual ~wxSocketImpl();
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
)
199 m_initialRecvBufferSize
= recv
;
200 m_initialSendBufferSize
= send
;
203 wxSocketError
SetLocal(GAddress
*address
);
204 wxSocketError
SetPeer(GAddress
*address
);
209 bool IsServer() const { return m_server
; }
211 GAddress
*GetLocal();
214 wxSocketError
GetError() const { return m_error
; }
215 bool IsOk() const { return m_error
== wxSOCKET_NOERROR
; }
217 // get the error code corresponding to the last operation
218 virtual wxSocketError
GetLastError() const = 0;
221 // creating/closing the socket
222 // --------------------------
224 // notice that SetLocal() must be called before creating the socket using
225 // any of the functions below
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
232 // wxSOCKET_IOERR - any other error.
234 // create a socket listening on the local address specified by SetLocal()
235 // (notice that DontDoBind() is ignored by this function)
236 wxSocketError
CreateServer();
238 // create a socket connected to the peer address specified by SetPeer()
239 // (notice that DontDoBind() is ignored by this function)
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
);
245 // create (and bind unless DontDoBind() had been called) an UDP socket
246 // associated with the given local address
247 wxSocketError
CreateUDP();
249 // may be called whether the socket was created or not, calls DoClose() if
250 // it was indeed created
253 // shuts down the writing end of the socket and closes it, this is a more
254 // graceful way to close
256 // does nothing if the socket wasn't created
263 virtual int Read(void *buffer
, int size
) = 0;
264 virtual int Write(const void *buffer
, int size
) = 0;
266 // basically a wrapper for select(): returns the condition of the socket,
267 // blocking for not longer than timeout if it is specified (otherwise just
268 // poll without blocking at all)
270 // flags defines what kind of conditions we're interested in, the return
271 // value is composed of a (possibly empty) subset of the bits set in flags
272 wxSocketEventFlags
Select(wxSocketEventFlags flags
,
273 const timeval
*timeout
= NULL
);
275 // convenient wrapper calling Select() with our default timeout
276 wxSocketEventFlags
SelectWithTimeout(wxSocketEventFlags flags
)
278 return Select(flags
, &m_timeout
);
281 // just a wrapper for accept(): it is called to create a new wxSocketImpl
282 // corresponding to a new server connection represented by the given
283 // wxSocketBase, returns NULL on error (including immediately if there are
284 // no pending connections as our sockets are non-blocking)
285 wxSocketImpl
*Accept(wxSocketBase
& wxsocket
);
291 // notify m_wxsocket about the given socket event by calling its (inaptly
292 // named) OnRequest() method
293 void NotifyOnStateChange(wxSocketNotify event
);
295 // TODO: make these fields protected and provide accessors for those of
296 // them that wxSocketBase really needs
300 int m_initialRecvBufferSize
;
301 int m_initialSendBufferSize
;
305 wxSocketError m_error
;
313 struct timeval m_timeout
;
316 wxSocketImpl(wxSocketBase
& wxsocket
);
318 // true if we're a listening stream socket
322 // called by Close() if we have a valid m_fd
323 virtual void DoClose() = 0;
325 // put this socket into non-blocking mode and enable monitoring this socket
326 // as part of the event loop
327 virtual void UnblockAndRegisterWithEventLoop() = 0;
329 // check that the socket wasn't created yet and that the given address
330 // (either m_local or m_peer depending on the socket kind) is valid and
331 // set m_error and return false if this is not the case
332 bool PreCreateCheck(GAddress
*addr
);
334 // set the given socket option: this just wraps setsockopt(SOL_SOCKET)
335 int SetSocketOption(int optname
, int optval
)
337 // although modern Unix systems use "const void *" for the 4th
338 // parameter here, old systems and Winsock still use "const char *"
339 return setsockopt(m_fd
, SOL_SOCKET
, optname
,
340 reinterpret_cast<const char *>(&optval
),
344 // set the given socket option to true value: this is an even simpler
345 // wrapper for setsockopt(SOL_SOCKET) for boolean options
346 int EnableSocketOption(int optname
)
348 return SetSocketOption(optname
, 1);
351 // apply the options to the (just created) socket and register it with the
352 // event loop by calling UnblockAndRegisterWithEventLoop()
355 // update local address after binding/connecting
356 wxSocketError
UpdateLocalAddress();
359 // set in ctor and never changed except that it's reset to NULL when the
360 // socket is shut down
361 wxSocketBase
*m_wxsocket
;
363 DECLARE_NO_COPY_CLASS(wxSocketImpl
)
366 #if defined(__WXMSW__)
367 #include "wx/msw/private/sockmsw.h"
369 #include "wx/unix/private/sockunix.h"
375 // TODO: make GAddress a real class instead of this mix of C and C++
377 // Represents a socket endpoint, i.e. -- in spite of its name -- not an address
378 // but an (address, port) pair
381 struct sockaddr
*m_addr
;
384 GAddressType m_family
;
387 wxSocketError m_error
;
390 GAddress
*GAddress_new();
391 GAddress
*GAddress_copy(GAddress
*address
);
392 void GAddress_destroy(GAddress
*address
);
394 void GAddress_SetFamily(GAddress
*address
, GAddressType type
);
395 GAddressType
GAddress_GetFamily(GAddress
*address
);
397 /* The use of any of the next functions will set the address family to
398 * the specific one. For example if you use GAddress_INET_SetHostName,
399 * address family will be implicitly set to AF_INET.
402 wxSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
);
403 wxSocketError
GAddress_INET_SetBroadcastAddress(GAddress
*address
);
404 wxSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
);
405 wxSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
406 unsigned long hostaddr
);
407 wxSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
408 const char *protocol
);
409 wxSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
);
411 wxSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
,
413 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
);
414 unsigned short GAddress_INET_GetPort(GAddress
*address
);
416 wxSocketError
_GAddress_translate_from(GAddress
*address
,
417 struct sockaddr
*addr
, int len
);
418 wxSocketError
_GAddress_translate_to (GAddress
*address
,
419 struct sockaddr
**addr
, int *len
);
420 wxSocketError
_GAddress_Init_INET(GAddress
*address
);
424 wxSocketError
GAddress_INET6_SetHostName(GAddress
*address
, const char *hostname
);
425 wxSocketError
GAddress_INET6_SetAnyAddress(GAddress
*address
);
426 wxSocketError
GAddress_INET6_SetHostAddress(GAddress
*address
,
427 struct in6_addr hostaddr
);
428 wxSocketError
GAddress_INET6_SetPortName(GAddress
*address
, const char *port
,
429 const char *protocol
);
430 wxSocketError
GAddress_INET6_SetPort(GAddress
*address
, unsigned short port
);
432 wxSocketError
GAddress_INET6_GetHostName(GAddress
*address
, char *hostname
,
434 wxSocketError
GAddress_INET6_GetHostAddress(GAddress
*address
,struct in6_addr
*hostaddr
);
435 unsigned short GAddress_INET6_GetPort(GAddress
*address
);
439 // these functions are available under all platforms but only implemented under
440 // Unix ones, elsewhere they just return wxSOCKET_INVADDR
441 wxSocketError
_GAddress_Init_UNIX(GAddress
*address
);
442 wxSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
);
443 wxSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
);
445 #endif /* wxUSE_SOCKETS */
447 #endif /* _WX_PRIVATE_SOCKET_H_ */