* Added wxsocket lib and sample (I hope I don't forget some file)
[wxWidgets.git] / include / wx / socket.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: socket.h
3 // Purpose: Socket handling classes
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: April 1997
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_NETWORK_SOCKET_H
12 #define _WX_NETWORK_SOCKET_H
13
14 #ifdef __GNUG__
15 #pragma interface
16 #endif
17
18 // ---------------------------------------------------------------------------
19 // Windows(tm) specific
20 // ---------------------------------------------------------------------------
21 #if defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
22 #include <winsock.h>
23 #include <wx/msw/private.h>
24
25 struct wxSockInternal {
26 UINT my_msg;
27 };
28
29 struct wxSockHandlerInternal {
30 HWND sockWin;
31 UINT firstAvailableMsg;
32 };
33 #endif // defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
34
35 // ---------------------------------------------------------------------------
36 // Unix specific
37 // ---------------------------------------------------------------------------
38 #if defined(__UNIX__) && defined(WXSOCK_INTERNAL)
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
42
43 // ---------------------------------------------------------------------------
44 // Athena specific
45 // ---------------------------------------------------------------------------
46 #if defined(__WXXT__) || defined(__WXMOTIF__)
47 #include <X11/Intrinsic.h>
48
49 struct wxSockInternal {
50 XtInputId sock_inputid, sock_outputid, sock_exceptid;
51 };
52 #endif
53
54 // ---------------------------------------------------------------------------
55 // GTK specific
56 // ---------------------------------------------------------------------------
57 #if defined(__WXGTK__)
58 #include <gdk/gdk.h>
59
60 struct wxSockInternal {
61 gint sock_inputid, sock_outputid, sock_exceptid;
62 };
63 #endif
64
65 #endif // defined(__UNIX__) && defined(WXSOCK_INTERNAL)
66
67 // ---------------------------------------------------------------------------
68 // wxSocket headers (generic)
69 // ---------------------------------------------------------------------------
70 #ifdef WXPREC
71 #include <wx/wxprec.h>
72 #else
73 #include <wx/wx.h>
74 #endif
75 #include "wx/sckaddr.h"
76
77 class WXDLLEXPORT wxSocketEvent;
78 class WXDLLEXPORT wxSocketHandler;
79 class WXDLLEXPORT wxSocketBase : public wxEvtHandler
80 {
81 DECLARE_CLASS(wxSocketBase)
82 public:
83
84 enum wxSockFlags { NONE=0, NOWAIT=1, WAITALL=2, SPEED=4 };
85 // Type of request
86 enum { REQ_READ=0x1, REQ_PEEK=0x2, REQ_WRITE=0x4, REQ_LOST=0x8,
87 REQ_ACCEPT=0x10, REQ_CONNECT=0x20};
88 enum { EVT_READ=0, EVT_PEEK=1, EVT_WRITE=2, EVT_LOST=3, EVT_ACCEPT=4,
89 EVT_CONNECT=5 };
90
91 typedef int wxRequestNotify;
92 typedef int wxRequestEvent;
93 typedef void (*wxSockCbk)(wxSocketBase& sock,wxRequestEvent evt,char *cdata);
94
95 protected:
96 wxList req_list[EVT_WRITE+1];
97
98 // Internal use for SaveState() and RestoreState()
99 class wxSockState : public wxObject {
100 public:
101 bool cbk_on;
102 wxSockCbk cbk;
103 char *cdata;
104 bool notif;
105 wxRequestNotify cbk_set;
106 wxSockFlags flags;
107 };
108 typedef struct {
109 char sig[4];
110 char len[4];
111 } SockMsg;
112 enum wxSockType { SOCK_CLIENT, SOCK_SERVER, SOCK_INTERNAL, SOCK_UNINIT };
113
114 wxSockFlags m_flags;
115 wxSockType m_type; // wxSocket type
116 bool m_connected, m_connecting; // State of the socket
117 int m_fd; // Socket file descriptors
118 int m_waitflags; // Wait flags
119 wxList m_states; // States list
120 wxSockCbk m_cbk; // C callback
121 char *m_cdata; // C callback data
122 int m_id; // Socket id (for event handler)
123 wxSocketHandler *m_handler; // the current socket handler
124 wxRequestNotify m_neededreq; // Specify which requet signals we need
125 bool m_cbkon;
126 char *m_unread; // The unread buf
127 size_t m_unrd_size; // The size of the unread buf
128 bool m_processing; // To prevent some endless loop
129 unsigned long m_timeout;
130 int m_wantbuf;
131 size_t m_lcount; // Last IO request size
132 int m_error; // Last IO error
133 bool m_notifyme;
134
135 struct wxSockInternal *m_internal; // System specific variables
136
137 public:
138 wxSocketBase();
139 virtual ~wxSocketBase();
140 virtual bool Close();
141
142 // Base IO
143 wxSocketBase& Peek(char* buffer, size_t nbytes);
144 wxSocketBase& Read(char* buffer, size_t nbytes);
145 wxSocketBase& Write(const char *buffer, size_t nbytes);
146 wxSocketBase& WriteMsg(const char *buffer, size_t nbytes);
147 wxSocketBase& ReadMsg(char* buffer, size_t nbytes);
148 wxSocketBase& Unread(const char *buffer, size_t nbytes);
149 void Discard();
150
151 // Try not to use this two methods (they sould be protected)
152 void CreatePushbackAfter(const char *buffer, size_t size);
153 void CreatePushbackBefore(const char *buffer, size_t size);
154
155 // Status
156 inline bool Ok() const { return (m_fd < 0 ? 0 : 1); };
157 inline bool Error() const { return (m_error != 0); };
158 inline bool IsConnected() const { return m_connected; };
159 inline bool IsDisconnected() const { return !IsConnected(); };
160 inline bool IsNoWait() const { return m_flags & NOWAIT; };
161 bool IsData() const;
162 inline size_t LastCount() const { return m_lcount; }
163 inline int LastError() const { return m_error; }
164
165 inline void SetFlags(wxSockFlags _flags);
166 inline void SetTimeout(unsigned long sec) { m_timeout = sec; }
167
168 // seconds = -1 means infinite wait
169 // seconds = 0 means no wait
170 // seconds > 0 means specified wait
171 bool Wait(long seconds = -1, long microseconds = 0);
172 bool WaitForRead(long seconds = -1, long microseconds = 0);
173 bool WaitForWrite(long seconds = -1, long microseconds = 0);
174 bool WaitForLost(long seconds = -1, long microseconds = 0);
175
176 // Save the current state of Socket
177 void SaveState();
178 void RestoreState();
179
180 // Setup external callback
181 wxSockCbk Callback(wxSockCbk cbk_);
182 char *CallbackData(char *data);
183
184 // Setup event handler
185 void SetEventHandler(wxEvtHandler& evt_hdlr, int id = -1);
186
187 // Method called when it happens something on the socket
188 void SetNotify(wxRequestNotify flags);
189 virtual void OnRequest(wxRequestEvent req_evt);
190
191 // Public internal callback
192 virtual void OldOnNotify(wxRequestEvent WXUNUSED(evt));
193
194 // Some info on the socket...
195 virtual bool GetPeer(wxSockAddress& addr_man) const;
196 virtual bool GetLocal(wxSockAddress& addr_man) const;
197
198 // Install or uninstall callbacks
199 void Notify(bool notify);
200
201 // So you can know what the socket driver is looking for ...
202 inline wxRequestNotify NeededReq() const { return m_neededreq; }
203
204 static wxRequestNotify EventToNotify(wxRequestEvent evt);
205
206 protected:
207 friend class wxSocketServer;
208 friend class wxSocketHandler;
209
210 wxSocketBase(wxSockFlags flags, wxSockType type);
211
212 bool _Wait(long seconds, long microseconds, int type);
213
214 // Set "my" handler
215 inline virtual void SetHandler(wxSocketHandler *handler)
216 { m_handler = handler; }
217
218 // Activate or disactivate callback
219 void SetupCallbacks();
220 void DestroyCallbacks();
221
222 // Pushback library
223 size_t GetPushback(char *buffer, size_t size, bool peek);
224
225 // To prevent many read or write on the same socket at the same time
226 // ==> cause strange things :-)
227 void WantSpeedBuffer(char *buffer, size_t size, wxRequestEvent req);
228 void WantBuffer(char *buffer, size_t size, wxRequestEvent req);
229
230 virtual bool DoRequests(wxRequestEvent req);
231 };
232
233 ////////////////////////////////////////////////////////////////////////
234
235 class WXDLLEXPORT wxSocketServer : public wxSocketBase
236 {
237 DECLARE_CLASS(wxSocketServer)
238 public:
239
240 // 'service' can be a name or a port-number
241
242 wxSocketServer(wxSockAddress& addr_man, wxSockFlags flags = wxSocketBase::NONE);
243
244 wxSocketBase* Accept();
245 bool AcceptWith(wxSocketBase& sock);
246 virtual void OnRequest(wxRequestEvent flags);
247 };
248
249 ////////////////////////////////////////////////////////////////////////
250
251 class WXDLLEXPORT wxSocketClient : public wxSocketBase
252 {
253 DECLARE_CLASS(wxSocketClient)
254 public:
255
256 wxSocketClient(wxSockFlags flags = wxSocketBase::NONE);
257 virtual ~wxSocketClient();
258
259 virtual bool Connect(wxSockAddress& addr_man, bool wait = TRUE);
260
261 bool WaitOnConnect(long seconds = -1);
262
263 virtual void OnRequest(wxRequestEvent flags);
264 };
265
266 ////////////////////////////////////////////////////////////////////////
267
268 class WXDLLEXPORT wxSocketHandler : public wxObject
269 {
270 DECLARE_CLASS(wxSocketHandler)
271 protected:
272 static wxSocketHandler *master;
273 #if defined(__WINDOWS__)
274 wxList *smsg_list;
275 struct wxSockHandlerInternal *internal;
276 #endif
277 wxList *socks;
278
279 public:
280 enum SockStatus { SOCK_NONE, SOCK_DATA, SOCK_CONNECT, SOCK_DISCONNECT,
281 SOCK_ERROR };
282
283 wxSocketHandler();
284 virtual ~wxSocketHandler();
285
286 void Register(wxSocketBase* sock);
287 void UnRegister(wxSocketBase* sock);
288
289 unsigned long Count() const;
290
291 // seconds = -1 means indefinite wait
292 // seconds = 0 means no wait
293 // seconds > 0 means specified wait
294
295 int Wait(long seconds = -1, long microseconds = 0);
296 void YieldSock();
297
298 wxSocketServer *CreateServer
299 (wxSockAddress& addr,
300 wxSocketBase::wxSockFlags flags = wxSocketBase::NONE);
301 wxSocketClient *CreateClient
302 (wxSocketBase::wxSockFlags flags = wxSocketBase::NONE);
303
304 // Create or reuse a socket handler
305 static wxSocketHandler& Master()
306 { return *((master) ? (master) : (master = new wxSocketHandler())); }
307
308 #if defined(WXSOCK_INTERNAL) && defined(__WINDOWS__)
309
310 friend LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd,
311 UINT message, WPARAM wParam, LPARAM lParam);
312
313 UINT NewMessage(wxSocketBase *sock);
314 void DestroyMessage(UINT msg);
315
316 HWND GetHWND() const;
317 #endif
318 };
319
320 class WXDLLEXPORT wxSocketEvent : public wxEvent {
321 DECLARE_DYNAMIC_CLASS(wxSocketEvent)
322 public:
323 wxSocketEvent(int id = 0);
324
325 wxSocketBase::wxRequestEvent SocketEvent() const { return m_skevt; }
326 public:
327 wxSocketBase::wxRequestEvent m_skevt;
328 };
329
330 typedef void (wxEvtHandler::*wxSocketEventFunction)(wxSocketEvent&);
331
332 #define wxEVT_SOCKET wxEVT_FIRST+301
333
334 #define EVT_SOCKET(id, func) { wxEVT_SOCKET, id, 0, (wxObjectEventFunction) (wxEventFunction) (wxSocketEventFunction) & func },
335
336 #endif