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