]> git.saurik.com Git - wxWidgets.git/blob - include/wx/socket.h
Fixed #12566 (assert on deletion) due to inconsistent commit
[wxWidgets.git] / include / wx / socket.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: socket.h
3 // Purpose: Socket handling classes
4 // Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
5 // Modified by:
6 // Created: April 1997
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_SOCKET_H_
13 #define _WX_SOCKET_H_
14
15 #include "wx/defs.h"
16
17 #if wxUSE_SOCKETS
18
19 // ---------------------------------------------------------------------------
20 // wxSocket headers
21 // ---------------------------------------------------------------------------
22
23 #include "wx/event.h"
24 #include "wx/sckaddr.h"
25 #include "wx/list.h"
26
27 class wxSocketImpl;
28
29 // ------------------------------------------------------------------------
30 // Types and constants
31 // ------------------------------------------------------------------------
32
33 // Types of different socket notifications or events.
34 //
35 // NB: the values here should be consecutive and start with 0 as they are
36 // used to construct the wxSOCKET_XXX_FLAG bit mask values below
37 enum wxSocketNotify
38 {
39 wxSOCKET_INPUT,
40 wxSOCKET_OUTPUT,
41 wxSOCKET_CONNECTION,
42 wxSOCKET_LOST
43 };
44
45 enum
46 {
47 wxSOCKET_INPUT_FLAG = 1 << wxSOCKET_INPUT,
48 wxSOCKET_OUTPUT_FLAG = 1 << wxSOCKET_OUTPUT,
49 wxSOCKET_CONNECTION_FLAG = 1 << wxSOCKET_CONNECTION,
50 wxSOCKET_LOST_FLAG = 1 << wxSOCKET_LOST
51 };
52
53 // this is a combination of the bit masks defined above
54 typedef int wxSocketEventFlags;
55
56 enum wxSocketError
57 {
58 wxSOCKET_NOERROR = 0,
59 wxSOCKET_INVOP,
60 wxSOCKET_IOERR,
61 wxSOCKET_INVADDR,
62 wxSOCKET_INVSOCK,
63 wxSOCKET_NOHOST,
64 wxSOCKET_INVPORT,
65 wxSOCKET_WOULDBLOCK,
66 wxSOCKET_TIMEDOUT,
67 wxSOCKET_MEMERR,
68 wxSOCKET_OPTERR
69 };
70
71 // socket options/flags bit masks
72 enum
73 {
74 wxSOCKET_NONE = 0,
75 wxSOCKET_NOWAIT = 1,
76 wxSOCKET_WAITALL = 2,
77 wxSOCKET_BLOCK = 4,
78 wxSOCKET_REUSEADDR = 8,
79 wxSOCKET_BROADCAST = 16,
80 wxSOCKET_NOBIND = 32
81 };
82
83 typedef int wxSocketFlags;
84
85 // socket kind values (badly defined, don't use)
86 enum wxSocketType
87 {
88 wxSOCKET_UNINIT,
89 wxSOCKET_CLIENT,
90 wxSOCKET_SERVER,
91 wxSOCKET_BASE,
92 wxSOCKET_DATAGRAM
93 };
94
95
96 // event
97 class WXDLLIMPEXP_FWD_NET wxSocketEvent;
98 wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_NET, wxEVT_SOCKET, wxSocketEvent);
99
100 // --------------------------------------------------------------------------
101 // wxSocketBase
102 // --------------------------------------------------------------------------
103
104 class WXDLLIMPEXP_NET wxSocketBase : public wxObject
105 {
106 public:
107 // Public interface
108 // ----------------
109
110 // ctors and dtors
111 wxSocketBase();
112 wxSocketBase(wxSocketFlags flags, wxSocketType type);
113 virtual ~wxSocketBase();
114 void Init();
115 bool Destroy();
116
117 // state
118 bool Ok() const { return IsOk(); }
119 bool IsOk() const { return m_impl != NULL; }
120 bool Error() const { return LastError() != wxSOCKET_NOERROR; }
121 bool IsClosed() const { return m_closed; }
122 bool IsConnected() const { return m_connected; }
123 bool IsData() { return WaitForRead(0, 0); }
124 bool IsDisconnected() const { return !IsConnected(); }
125 wxUint32 LastCount() const { return m_lcount; }
126 wxSocketError LastError() const;
127 void SaveState();
128 void RestoreState();
129
130 // addresses
131 virtual bool GetLocal(wxSockAddress& addr_man) const;
132 virtual bool GetPeer(wxSockAddress& addr_man) const;
133 virtual bool SetLocal(const wxIPV4address& local);
134
135 // base IO
136 virtual bool Close();
137 void ShutdownOutput();
138 wxSocketBase& Discard();
139 wxSocketBase& Peek(void* buffer, wxUint32 nbytes);
140 wxSocketBase& Read(void* buffer, wxUint32 nbytes);
141 wxSocketBase& ReadMsg(void *buffer, wxUint32 nbytes);
142 wxSocketBase& Unread(const void *buffer, wxUint32 nbytes);
143 wxSocketBase& Write(const void *buffer, wxUint32 nbytes);
144 wxSocketBase& WriteMsg(const void *buffer, wxUint32 nbytes);
145
146 // all Wait() functions wait until their condition is satisfied or the
147 // timeout expires; if seconds == -1 (default) then m_timeout value is used
148 //
149 // it is also possible to call InterruptWait() to cancel any current Wait()
150
151 // wait for anything at all to happen with this socket
152 bool Wait(long seconds = -1, long milliseconds = 0);
153
154 // wait until we can read from or write to the socket without blocking
155 // (notice that this does not mean that the operation will succeed but only
156 // that it will return immediately)
157 bool WaitForRead(long seconds = -1, long milliseconds = 0);
158 bool WaitForWrite(long seconds = -1, long milliseconds = 0);
159
160 // wait until the connection is terminated
161 bool WaitForLost(long seconds = -1, long milliseconds = 0);
162
163 void InterruptWait() { m_interrupt = true; }
164
165
166 wxSocketFlags GetFlags() const { return m_flags; }
167 void SetFlags(wxSocketFlags flags);
168 virtual void SetTimeout(long seconds);
169 long GetTimeout() const { return m_timeout; }
170
171 bool GetOption(int level, int optname, void *optval, int *optlen);
172 bool SetOption(int level, int optname, const void *optval, int optlen);
173 wxUint32 GetLastIOSize() const { return m_lcount; }
174
175 // event handling
176 void *GetClientData() const { return m_clientData; }
177 void SetClientData(void *data) { m_clientData = data; }
178 void SetEventHandler(wxEvtHandler& handler, int id = wxID_ANY);
179 void SetNotify(wxSocketEventFlags flags);
180 void Notify(bool notify);
181
182 // initialize/shutdown the sockets (done automatically so there is no need
183 // to call these functions usually)
184 //
185 // should always be called from the main thread only so one of the cases
186 // where they should indeed be called explicitly is when the first wxSocket
187 // object in the application is created in a different thread
188 static bool Initialize();
189 static void Shutdown();
190
191 // check if wxSocket had been already initialized
192 //
193 // notice that this function should be only called from the main thread as
194 // otherwise it is inherently unsafe because Initialize/Shutdown() may be
195 // called concurrently with it in the main thread
196 static bool IsInitialized();
197
198 // Implementation from now on
199 // --------------------------
200
201 // do not use, should be private (called from wxSocketImpl only)
202 void OnRequest(wxSocketNotify notify);
203
204 // do not use, not documented nor supported
205 bool IsNoWait() const { return ((m_flags & wxSOCKET_NOWAIT) != 0); }
206 wxSocketType GetType() const { return m_type; }
207
208 private:
209 friend class wxSocketClient;
210 friend class wxSocketServer;
211 friend class wxDatagramSocket;
212
213 // low level IO
214 wxUint32 DoRead(void* buffer, wxUint32 nbytes);
215 wxUint32 DoWrite(const void *buffer, wxUint32 nbytes);
216
217 // wait until the given flags are set for this socket or the given timeout
218 // (or m_timeout) expires
219 //
220 // notice that wxSOCKET_LOST_FLAG is always taken into account and the
221 // function returns -1 if the connection was lost; otherwise it returns
222 // true if any of the events specified by flags argument happened or false
223 // if the timeout expired
224 int DoWait(long timeout, wxSocketEventFlags flags);
225
226 // a helper calling DoWait() using the same convention as the public
227 // WaitForXXX() functions use, i.e. use our timeout if seconds == -1 or the
228 // specified timeout otherwise
229 int DoWait(long seconds, long milliseconds, wxSocketEventFlags flags);
230
231 // another helper calling DoWait() using our m_timeout
232 int DoWaitWithTimeout(wxSocketEventFlags flags)
233 {
234 return DoWait(m_timeout*1000, flags);
235 }
236
237 // pushback buffer
238 void Pushback(const void *buffer, wxUint32 size);
239 wxUint32 GetPushback(void *buffer, wxUint32 size, bool peek);
240
241 // store the given error as the LastError()
242 void SetError(wxSocketError error);
243
244 private:
245 // socket
246 wxSocketImpl *m_impl; // port-specific implementation
247 wxSocketType m_type; // wxSocket type
248
249 // state
250 wxSocketFlags m_flags; // wxSocket flags
251 bool m_connected; // connected?
252 bool m_establishing; // establishing connection?
253 bool m_reading; // busy reading?
254 bool m_writing; // busy writing?
255 bool m_closed; // was the other end closed?
256 wxUint32 m_lcount; // last IO transaction size
257 unsigned long m_timeout; // IO timeout value in seconds
258 // (TODO: remove, wxSocketImpl has it too)
259 wxList m_states; // stack of states (TODO: remove!)
260 bool m_interrupt; // interrupt ongoing wait operations?
261 bool m_beingDeleted; // marked for delayed deletion?
262 wxIPV4address m_localAddress; // bind to local address?
263
264 // pushback buffer
265 void *m_unread; // pushback buffer
266 wxUint32 m_unrd_size; // pushback buffer size
267 wxUint32 m_unrd_cur; // pushback pointer (index into buffer)
268
269 // events
270 int m_id; // socket id
271 wxEvtHandler *m_handler; // event handler
272 void *m_clientData; // client data for events
273 bool m_notify; // notify events to users?
274 wxSocketEventFlags m_eventmask; // which events to notify?
275 wxSocketEventFlags m_eventsgot; // collects events received in OnRequest()
276
277
278 friend class wxSocketReadGuard;
279 friend class wxSocketWriteGuard;
280
281 wxDECLARE_NO_COPY_CLASS(wxSocketBase);
282 DECLARE_CLASS(wxSocketBase)
283 };
284
285
286 // --------------------------------------------------------------------------
287 // wxSocketServer
288 // --------------------------------------------------------------------------
289
290 class WXDLLIMPEXP_NET wxSocketServer : public wxSocketBase
291 {
292 public:
293 wxSocketServer(const wxSockAddress& addr,
294 wxSocketFlags flags = wxSOCKET_NONE);
295
296 wxSocketBase* Accept(bool wait = true);
297 bool AcceptWith(wxSocketBase& socket, bool wait = true);
298
299 bool WaitForAccept(long seconds = -1, long milliseconds = 0);
300
301 wxDECLARE_NO_COPY_CLASS(wxSocketServer);
302 DECLARE_CLASS(wxSocketServer)
303 };
304
305
306 // --------------------------------------------------------------------------
307 // wxSocketClient
308 // --------------------------------------------------------------------------
309
310 class WXDLLIMPEXP_NET wxSocketClient : public wxSocketBase
311 {
312 public:
313 wxSocketClient(wxSocketFlags flags = wxSOCKET_NONE);
314
315 virtual bool Connect(const wxSockAddress& addr, bool wait = true);
316 bool Connect(const wxSockAddress& addr,
317 const wxSockAddress& local,
318 bool wait = true);
319
320 bool WaitOnConnect(long seconds = -1, long milliseconds = 0);
321
322 // Sets initial socket buffer sizes using the SO_SNDBUF and SO_RCVBUF
323 // options before calling connect (either one can be -1 to leave it
324 // unchanged)
325 void SetInitialSocketBuffers(int recv, int send)
326 {
327 m_initialRecvBufferSize = recv;
328 m_initialSendBufferSize = send;
329 }
330
331 private:
332 virtual bool DoConnect(const wxSockAddress& addr,
333 const wxSockAddress* local,
334 bool wait = true);
335
336 // buffer sizes, -1 if unset and defaults should be used
337 int m_initialRecvBufferSize;
338 int m_initialSendBufferSize;
339
340 wxDECLARE_NO_COPY_CLASS(wxSocketClient);
341 DECLARE_CLASS(wxSocketClient)
342 };
343
344
345 // --------------------------------------------------------------------------
346 // wxDatagramSocket
347 // --------------------------------------------------------------------------
348
349 // WARNING: still in alpha stage
350
351 class WXDLLIMPEXP_NET wxDatagramSocket : public wxSocketBase
352 {
353 public:
354 wxDatagramSocket(const wxSockAddress& addr,
355 wxSocketFlags flags = wxSOCKET_NONE);
356
357 wxDatagramSocket& RecvFrom(wxSockAddress& addr,
358 void *buf,
359 wxUint32 nBytes);
360 wxDatagramSocket& SendTo(const wxSockAddress& addr,
361 const void* buf,
362 wxUint32 nBytes);
363
364 /* TODO:
365 bool Connect(wxSockAddress& addr);
366 */
367
368 private:
369 wxDECLARE_NO_COPY_CLASS(wxDatagramSocket);
370 DECLARE_CLASS(wxDatagramSocket)
371 };
372
373
374 // --------------------------------------------------------------------------
375 // wxSocketEvent
376 // --------------------------------------------------------------------------
377
378 class WXDLLIMPEXP_NET wxSocketEvent : public wxEvent
379 {
380 public:
381 wxSocketEvent(int id = 0)
382 : wxEvent(id, wxEVT_SOCKET)
383 {
384 }
385
386 wxSocketNotify GetSocketEvent() const { return m_event; }
387 wxSocketBase *GetSocket() const
388 { return (wxSocketBase *) GetEventObject(); }
389 void *GetClientData() const { return m_clientData; }
390
391 virtual wxEvent *Clone() const { return new wxSocketEvent(*this); }
392 virtual wxEventCategory GetEventCategory() const { return wxEVT_CATEGORY_SOCKET; }
393
394 public:
395 wxSocketNotify m_event;
396 void *m_clientData;
397
398 DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxSocketEvent)
399 };
400
401
402 typedef void (wxEvtHandler::*wxSocketEventFunction)(wxSocketEvent&);
403
404 #define wxSocketEventHandler(func) \
405 wxEVENT_HANDLER_CAST(wxSocketEventFunction, func)
406
407 #define EVT_SOCKET(id, func) \
408 wx__DECLARE_EVT1(wxEVT_SOCKET, id, wxSocketEventHandler(func))
409
410 #endif // wxUSE_SOCKETS
411
412 #endif // _WX_SOCKET_H_
413