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