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