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