1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:    Socket handler classes 
   4 // Authors:    Guilhem Lavaux, Guillermo Rodriguez Garcia 
   6 // Copyright:  (C) 1999-1997, Guilhem Lavaux 
   7 //             (C) 2000-1999, Guillermo Rodriguez Garcia 
   9 // License:    see wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ========================================================================== 
  14 // ========================================================================== 
  17 #pragma implementation "socket.h" 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  31 #include "wx/object.h" 
  32 #include "wx/string.h" 
  35 #include "wx/module.h" 
  41   #include "wx/gdicmn.h"      // for wxPendingDelete 
  44 #include "wx/sckaddr.h" 
  45 #include "wx/socket.h" 
  47 // -------------------------------------------------------------------------- 
  48 // macros and constants 
  49 // -------------------------------------------------------------------------- 
  52 #define MAX_DISCARD_SIZE (10 * 1024) 
  54 // what to do within waits: in wxBase we don't do anything as we don't have 
  55 // the event loop anyhow (for now). In GUI apps we have 2 cases: from the main 
  56 // thread itself we have to call wxYield() to let the events (including the 
  57 // GUI events and the low-level (not wxWindows) events from GSocket) be 
  58 // processed. From another thread it is enough to just call wxThread::Yield() 
  59 // which will give away the rest of our time slice: the explanation is that 
  60 // the events will be processed by the main thread anyhow, without calling 
  61 // wxYield(), but we don't want to eat the CPU time uselessly while sitting 
  62 // in the loop waiting for the data 
  65         #define PROCESS_EVENTS()        \ 
  67             if ( wxThread::IsMain() )   \ 
  72     #else // !wxUSE_THREADS 
  73         #define PROCESS_EVENTS() wxYield() 
  74     #endif // wxUSE_THREADS/!wxUSE_THREADS 
  76     #define PROCESS_EVENTS() 
  77 #endif // wxUSE_GUI/!wxUSE_GUI 
  79 #define wxTRACE_Socket _T("wxSocket") 
  81 // -------------------------------------------------------------------------- 
  83 // -------------------------------------------------------------------------- 
  85 IMPLEMENT_CLASS(wxSocketBase
, wxObject
) 
  86 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
) 
  87 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
) 
  88 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
) 
  89 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
) 
  91 // -------------------------------------------------------------------------- 
  93 // -------------------------------------------------------------------------- 
  95 class wxSocketState 
: public wxObject
 
  98   wxSocketFlags            m_flags
; 
  99   wxSocketEventFlags       m_eventmask
; 
 102 #if WXWIN_COMPATIBILITY 
 103   wxSocketBase::wxSockCbk  m_cbk
; 
 105 #endif // WXWIN_COMPATIBILITY 
 108   wxSocketState() : wxObject() {} 
 110     DECLARE_NO_COPY_CLASS(wxSocketState
) 
 113 // ========================================================================== 
 115 // ========================================================================== 
 117 // -------------------------------------------------------------------------- 
 118 // Initialization and shutdown 
 119 // -------------------------------------------------------------------------- 
 121 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses 
 122 //           to m_countInit with a crit section 
 123 size_t wxSocketBase::m_countInit 
= 0; 
 125 bool wxSocketBase::IsInitialized() 
 127     return m_countInit 
> 0; 
 130 bool wxSocketBase::Initialize() 
 132     if ( !m_countInit
++ ) 
 134         if ( !GSocket_Init() ) 
 145 void wxSocketBase::Shutdown() 
 147     // we should be initialized 
 148     wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") ); 
 149     if ( !--m_countInit 
) 
 155 // -------------------------------------------------------------------------- 
 157 // -------------------------------------------------------------------------- 
 159 void wxSocketBase::Init() 
 162   m_type         
= wxSOCKET_UNINIT
; 
 173   m_beingDeleted 
= FALSE
; 
 186 #if WXWIN_COMPATIBILITY 
 189 #endif // WXWIN_COMPATIBILITY 
 191   if ( !IsInitialized() ) 
 193       // this Initialize() will be undone by wxSocketModule::OnExit(), all the 
 194       // other calls to it should be matched by a call to Shutdown() 
 199 wxSocketBase::wxSocketBase() 
 204 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
) 
 212 wxSocketBase::~wxSocketBase() 
 214   // Just in case the app called Destroy() *and* then deleted 
 215   // the socket immediately: don't leave dangling pointers. 
 217   wxPendingDelete
.DeleteObject(this); 
 220   // Shutdown and close the socket 
 224   // Destroy the GSocket object 
 226     GSocket_destroy(m_socket
); 
 228   // Free the pushback buffer 
 233 bool wxSocketBase::Destroy() 
 235   // Delayed destruction: the socket will be deleted during the next 
 236   // idle loop iteration. This ensures that all pending events have 
 238   m_beingDeleted 
= TRUE
; 
 240   // Shutdown and close the socket 
 243   // Supress events from now on 
 247   if ( !wxPendingDelete
.Member(this) ) 
 248     wxPendingDelete
.Append(this); 
 256 // -------------------------------------------------------------------------- 
 258 // -------------------------------------------------------------------------- 
 260 // The following IO operations update m_error and m_lcount: 
 261 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard} 
 263 // TODO: Should Connect, Accept and AcceptWith update m_error? 
 265 bool wxSocketBase::Close() 
 267   // Interrupt pending waits 
 273     GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
 274                                     GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
); 
 276     // Shutdown the connection 
 277     GSocket_Shutdown(m_socket
); 
 281   m_establishing 
= FALSE
; 
 285 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
) 
 290   m_lcount 
= _Read(buffer
, nbytes
); 
 292   // If in wxSOCKET_WAITALL mode, all bytes should have been read. 
 293   if (m_flags 
& wxSOCKET_WAITALL
) 
 294     m_error 
= (m_lcount 
!= nbytes
); 
 296     m_error 
= (m_lcount 
== 0); 
 298   // Allow read events from now on 
 304 wxUint32 
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
) 
 309   // Try the pushback buffer first 
 310   total 
= GetPushback(buffer
, nbytes
, FALSE
); 
 312   buffer  
= (char *)buffer 
+ total
; 
 314   // Return now in one of the following cases: 
 315   // - the socket is invalid, 
 316   // - we got all the data, 
 317   // - we got *some* data and we are not using wxSOCKET_WAITALL. 
 320        ((total 
!= 0) && !(m_flags 
& wxSOCKET_WAITALL
)) ) 
 323   // Possible combinations (they are checked in this order) 
 325   // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK) 
 329   if (m_flags 
& wxSOCKET_NOWAIT
) 
 331     GSocket_SetNonBlocking(m_socket
, 1); 
 332     ret 
= GSocket_Read(m_socket
, (char *)buffer
, nbytes
); 
 333     GSocket_SetNonBlocking(m_socket
, 0); 
 344       if ( !(m_flags 
& wxSOCKET_BLOCK
) && !WaitForRead() ) 
 347       ret 
= GSocket_Read(m_socket
, (char *)buffer
, nbytes
); 
 353         buffer  
= (char *)buffer 
+ ret
; 
 356       // If we got here and wxSOCKET_WAITALL is not set, we can leave 
 357       // now. Otherwise, wait until we recv all the data or until there 
 360       more 
= (ret 
> 0 && nbytes 
> 0 && (m_flags 
& wxSOCKET_WAITALL
)); 
 367 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
) 
 369   wxUint32 len
, len2
, sig
, total
; 
 374     unsigned char sig
[4]; 
 375     unsigned char len
[4]; 
 384   SetFlags((m_flags 
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
); 
 386   if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
)) 
 389   sig 
= (wxUint32
)msg
.sig
[0]; 
 390   sig 
|= (wxUint32
)(msg
.sig
[1] << 8); 
 391   sig 
|= (wxUint32
)(msg
.sig
[2] << 16); 
 392   sig 
|= (wxUint32
)(msg
.sig
[3] << 24); 
 394   if (sig 
!= 0xfeeddead) 
 396     wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); 
 400   len 
= (wxUint32
)msg
.len
[0]; 
 401   len 
|= (wxUint32
)(msg
.len
[1] << 8); 
 402   len 
|= (wxUint32
)(msg
.len
[2] << 16); 
 403   len 
|= (wxUint32
)(msg
.len
[3] << 24); 
 413   // Don't attemp to read if the msg was zero bytes long. 
 416     total 
= _Read(buffer
, len
); 
 423     char *discard_buffer 
= new char[MAX_DISCARD_SIZE
]; 
 426     // NOTE: discarded bytes don't add to m_lcount. 
 429       discard_len 
= ((len2 
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE 
: len2
); 
 430       discard_len 
= _Read(discard_buffer
, (wxUint32
)discard_len
); 
 431       len2 
-= (wxUint32
)discard_len
; 
 433     while ((discard_len 
> 0) && len2
); 
 435     delete [] discard_buffer
; 
 440   if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
)) 
 443   sig 
= (wxUint32
)msg
.sig
[0]; 
 444   sig 
|= (wxUint32
)(msg
.sig
[1] << 8); 
 445   sig 
|= (wxUint32
)(msg
.sig
[2] << 16); 
 446   sig 
|= (wxUint32
)(msg
.sig
[3] << 24); 
 448   if (sig 
!= 0xdeadfeed) 
 450     wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); 
 466 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
) 
 471   m_lcount 
= _Read(buffer
, nbytes
); 
 472   Pushback(buffer
, m_lcount
); 
 474   // If in wxSOCKET_WAITALL mode, all bytes should have been read. 
 475   if (m_flags 
& wxSOCKET_WAITALL
) 
 476     m_error 
= (m_lcount 
!= nbytes
); 
 478     m_error 
= (m_lcount 
== 0); 
 480   // Allow read events again 
 486 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
) 
 491   m_lcount 
= _Write(buffer
, nbytes
); 
 493   // If in wxSOCKET_WAITALL mode, all bytes should have been written. 
 494   if (m_flags 
& wxSOCKET_WAITALL
) 
 495     m_error 
= (m_lcount 
!= nbytes
); 
 497     m_error 
= (m_lcount 
== 0); 
 499   // Allow write events again 
 505 wxUint32 
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
) 
 510   // If the socket is invalid or parameters are ill, return immediately 
 511   if (!m_socket 
|| !buffer 
|| !nbytes
) 
 514   // Possible combinations (they are checked in this order) 
 516   // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK) 
 520   if (m_flags 
& wxSOCKET_NOWAIT
) 
 522     GSocket_SetNonBlocking(m_socket
, 1); 
 523     ret 
= GSocket_Write(m_socket
, (const char *)buffer
, nbytes
); 
 524     GSocket_SetNonBlocking(m_socket
, 0); 
 535       if ( !(m_flags 
& wxSOCKET_BLOCK
) && !WaitForWrite() ) 
 538       ret 
= GSocket_Write(m_socket
, (const char *)buffer
, nbytes
); 
 544         buffer  
= (const char *)buffer 
+ ret
; 
 547       // If we got here and wxSOCKET_WAITALL is not set, we can leave 
 548       // now. Otherwise, wait until we send all the data or until there 
 551       more 
= (ret 
> 0 && nbytes 
> 0 && (m_flags 
& wxSOCKET_WAITALL
)); 
 558 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
) 
 565     unsigned char sig
[4]; 
 566     unsigned char len
[4]; 
 575   SetFlags((m_flags 
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
); 
 577   msg
.sig
[0] = (unsigned char) 0xad; 
 578   msg
.sig
[1] = (unsigned char) 0xde; 
 579   msg
.sig
[2] = (unsigned char) 0xed; 
 580   msg
.sig
[3] = (unsigned char) 0xfe; 
 582   msg
.len
[0] = (unsigned char) (nbytes 
& 0xff); 
 583   msg
.len
[1] = (unsigned char) ((nbytes 
>> 8) & 0xff); 
 584   msg
.len
[2] = (unsigned char) ((nbytes 
>> 16) & 0xff); 
 585   msg
.len
[3] = (unsigned char) ((nbytes 
>> 24) & 0xff); 
 587   if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
)) 
 590   total 
= _Write(buffer
, nbytes
); 
 595   msg
.sig
[0] = (unsigned char) 0xed; 
 596   msg
.sig
[1] = (unsigned char) 0xfe; 
 597   msg
.sig
[2] = (unsigned char) 0xad; 
 598   msg
.sig
[3] = (unsigned char) 0xde; 
 599   msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0; 
 601   if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
)) 
 615 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
) 
 618     Pushback(buffer
, nbytes
); 
 626 wxSocketBase
& wxSocketBase::Discard() 
 629   char *buffer 
= new char[MAX_DISCARD_SIZE
]; 
 637   SetFlags(wxSOCKET_NOWAIT
); 
 641     ret 
= _Read(buffer
, MAX_DISCARD_SIZE
); 
 644   while (ret 
== MAX_DISCARD_SIZE
); 
 650   // Allow read events again 
 656 // -------------------------------------------------------------------------- 
 658 // -------------------------------------------------------------------------- 
 660 // All Wait functions poll the socket using GSocket_Select() to 
 661 // check for the specified combination of conditions, until one 
 662 // of these conditions become true, an error occurs, or the 
 663 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so 
 664 // this won't block the GUI. 
 666 bool wxSocketBase::_Wait(long seconds
, 
 668                          wxSocketEventFlags flags
) 
 670   GSocketEventFlags result
; 
 673   // Set this to TRUE to interrupt ongoing waits 
 676   // Check for valid socket 
 680   // Check for valid timeout value. 
 682     timeout 
= seconds 
* 1000 + milliseconds
; 
 684     timeout 
= m_timeout 
* 1000; 
 686   // Wait in an active polling loop. 
 688   // NOTE: We duplicate some of the code in OnRequest, but this doesn't 
 689   //   hurt. It has to be here because the (GSocket) event might arrive 
 690   //   a bit delayed, and it has to be in OnRequest as well because we 
 691   //   don't know whether the Wait functions are being used. 
 693   // Do this at least once (important if timeout == 0, when 
 694   // we are just polling). Also, if just polling, do not yield. 
 701     result 
= GSocket_Select(m_socket
, flags 
| GSOCK_LOST_FLAG
); 
 703     // Incoming connection (server) or connection established (client) 
 704     if (result 
& GSOCK_CONNECTION_FLAG
) 
 707       m_establishing 
= FALSE
; 
 711     // Data available or output buffer ready 
 712     if ((result 
& GSOCK_INPUT_FLAG
) || (result 
& GSOCK_OUTPUT_FLAG
)) 
 718     if (result 
& GSOCK_LOST_FLAG
) 
 721       m_establishing 
= FALSE
; 
 722       return (flags 
& GSOCK_LOST_FLAG
) != 0; 
 726     if ((!timeout
) || (chrono
.Time() > timeout
) || (m_interrupt
)) 
 735 bool wxSocketBase::Wait(long seconds
, long milliseconds
) 
 737   return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG 
| 
 739                                       GSOCK_CONNECTION_FLAG 
| 
 743 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
) 
 745   // Check pushback buffer before entering _Wait 
 749   // Note that GSOCK_INPUT_LOST has to be explicitly passed to 
 750   // _Wait becuase of the semantics of WaitForRead: a return 
 751   // value of TRUE means that a GSocket_Read call will return 
 752   // immediately, not that there is actually data to read. 
 754   return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG 
| 
 758 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
) 
 760   return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
); 
 763 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
) 
 765   return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
); 
 768 // -------------------------------------------------------------------------- 
 770 // -------------------------------------------------------------------------- 
 773 // Get local or peer address 
 776 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const 
 783   peer 
= GSocket_GetPeer(m_socket
); 
 785     // copying a null address would just trigger an assert anyway 
 790   addr_man
.SetAddress(peer
); 
 791   GAddress_destroy(peer
); 
 796 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const 
 803   local 
= GSocket_GetLocal(m_socket
); 
 804   addr_man
.SetAddress(local
); 
 805   GAddress_destroy(local
); 
 811 // Save and restore socket state 
 814 void wxSocketBase::SaveState() 
 816   wxSocketState 
*state
; 
 818   state 
= new wxSocketState(); 
 820   state
->m_flags      
= m_flags
; 
 821   state
->m_notify     
= m_notify
; 
 822   state
->m_eventmask  
= m_eventmask
; 
 823   state
->m_clientData 
= m_clientData
; 
 824 #if WXWIN_COMPATIBILITY 
 825   state
->m_cbk        
= m_cbk
; 
 826   state
->m_cdata      
= m_cdata
; 
 827 #endif // WXWIN_COMPATIBILITY 
 829   m_states
.Append(state
); 
 832 void wxSocketBase::RestoreState() 
 835   wxSocketState 
*state
; 
 837   node 
= m_states
.Last(); 
 841   state 
= (wxSocketState 
*)node
->Data(); 
 843   m_flags      
= state
->m_flags
; 
 844   m_notify     
= state
->m_notify
; 
 845   m_eventmask  
= state
->m_eventmask
; 
 846   m_clientData 
= state
->m_clientData
; 
 847 #if WXWIN_COMPATIBILITY 
 848   m_cbk        
= state
->m_cbk
; 
 849   m_cdata      
= state
->m_cdata
; 
 850 #endif // WXWIN_COMPATIBILITY 
 860 void wxSocketBase::SetTimeout(long seconds
) 
 865     GSocket_SetTimeout(m_socket
, m_timeout 
* 1000); 
 868 void wxSocketBase::SetFlags(wxSocketFlags flags
) 
 874 // -------------------------------------------------------------------------- 
 875 // Callbacks (now obsolete - use events instead) 
 876 // -------------------------------------------------------------------------- 
 878 #if WXWIN_COMPATIBILITY 
 880 wxSocketBase::wxSockCbk 
wxSocketBase::Callback(wxSockCbk cbk_
) 
 882   wxSockCbk old_cbk 
= cbk_
; 
 888 char *wxSocketBase::CallbackData(char *data
) 
 890   char *old_data 
= m_cdata
; 
 896 #endif // WXWIN_COMPATIBILITY 
 898 // -------------------------------------------------------------------------- 
 900 // -------------------------------------------------------------------------- 
 902 // A note on how events are processed, which is probably the most 
 903 // difficult thing to get working right while keeping the same API 
 904 // and functionality for all platforms. 
 906 // When GSocket detects an event, it calls wx_socket_callback, which in 
 907 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket 
 908 // object. OnRequest does some housekeeping, and if the event is to be 
 909 // propagated to the user, it creates a new wxSocketEvent object and 
 910 // posts it. The event is not processed immediately, but delayed with 
 911 // AddPendingEvent instead. This is necessary in order to decouple the 
 912 // event processing from wx_socket_callback; otherwise, subsequent IO 
 913 // calls made from the user event handler would fail, as gtk callbacks 
 914 // are not reentrant. 
 916 // Note that, unlike events, user callbacks (now deprecated) are _not_ 
 917 // decoupled from wx_socket_callback and thus they suffer from a variety 
 918 // of problems. Avoid them where possible and use events instead. 
 921 void LINKAGEMODE 
wx_socket_callback(GSocket 
* WXUNUSED(socket
), 
 922                                     GSocketEvent notification
, 
 925   wxSocketBase 
*sckobj 
= (wxSocketBase 
*)cdata
; 
 927   sckobj
->OnRequest((wxSocketNotify
) notification
); 
 930 void wxSocketBase::OnRequest(wxSocketNotify notification
) 
 932   // NOTE: We duplicate some of the code in _Wait, but this doesn't 
 933   //   hurt. It has to be here because the (GSocket) event might arrive 
 934   //   a bit delayed, and it has to be in _Wait as well because we don't 
 935   //   know whether the Wait functions are being used. 
 939     case wxSOCKET_CONNECTION
: 
 940       m_establishing 
= FALSE
; 
 944     // If we are in the middle of a R/W operation, do not 
 945     // propagate events to users. Also, filter 'late' events 
 946     // which are no longer valid. 
 949       if (m_reading 
|| !GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
)) 
 953     case wxSOCKET_OUTPUT
: 
 954       if (m_writing 
|| !GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
)) 
 960       m_establishing 
= FALSE
; 
 967   // Schedule the event 
 969   wxSocketEventFlags flag 
= 0; 
 970   switch (notification
) 
 972     case GSOCK_INPUT
:      flag 
= GSOCK_INPUT_FLAG
; break; 
 973     case GSOCK_OUTPUT
:     flag 
= GSOCK_OUTPUT_FLAG
; break; 
 974     case GSOCK_CONNECTION
: flag 
= GSOCK_CONNECTION_FLAG
; break; 
 975     case GSOCK_LOST
:       flag 
= GSOCK_LOST_FLAG
; break; 
 977       wxLogWarning(_("wxSocket: unknown event!.")); 
 981   if (((m_eventmask 
& flag
) == flag
) && m_notify
) 
 985       wxSocketEvent 
event(m_id
); 
 986       event
.m_event      
= notification
; 
 987       event
.m_clientData 
= m_clientData
; 
 988       event
.SetEventObject(this); 
 990       m_handler
->AddPendingEvent(event
); 
 993 #if WXWIN_COMPATIBILITY 
 995       m_cbk(*this, notification
, m_cdata
); 
 996 #endif // WXWIN_COMPATIBILITY 
1000 void wxSocketBase::Notify(bool notify
) 
1005 void wxSocketBase::SetNotify(wxSocketEventFlags flags
) 
1007   m_eventmask 
= flags
; 
1010 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
) 
1012   m_handler 
= &handler
; 
1016 // -------------------------------------------------------------------------- 
1018 // -------------------------------------------------------------------------- 
1020 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
) 
1024   if (m_unread 
== NULL
) 
1025     m_unread 
= malloc(size
); 
1030     tmp 
= malloc(m_unrd_size 
+ size
); 
1031     memcpy((char *)tmp 
+ size
, m_unread
, m_unrd_size
); 
1037   m_unrd_size 
+= size
; 
1039   memcpy(m_unread
, buffer
, size
); 
1042 wxUint32 
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
) 
1047   if (size 
> (m_unrd_size
-m_unrd_cur
)) 
1048     size 
= m_unrd_size
-m_unrd_cur
; 
1050   memcpy(buffer
, (char *)m_unread 
+ m_unrd_cur
, size
); 
1055     if (m_unrd_size 
== m_unrd_cur
) 
1068 // ========================================================================== 
1070 // ========================================================================== 
1072 // -------------------------------------------------------------------------- 
1074 // -------------------------------------------------------------------------- 
1076 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
, 
1077                                wxSocketFlags flags
) 
1078               : wxSocketBase(flags
, wxSOCKET_SERVER
) 
1080     wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") ); 
1082     m_socket 
= GSocket_new(); 
1086         wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") ); 
1090         // Setup the socket as server 
1092     GSocket_SetLocal(m_socket
, addr_man
.GetAddress()); 
1093     if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
) 
1095         GSocket_destroy(m_socket
); 
1098         wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") ); 
1102     GSocket_SetTimeout(m_socket
, m_timeout 
* 1000); 
1103     GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
1104                                   GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
, 
1105                                   wx_socket_callback
, (char *)this); 
1108 // -------------------------------------------------------------------------- 
1110 // -------------------------------------------------------------------------- 
1112 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
) 
1114   GSocket 
*child_socket
; 
1119   // If wait == FALSE, then the call should be nonblocking. 
1120   // When we are finished, we put the socket to blocking mode 
1124     GSocket_SetNonBlocking(m_socket
, 1); 
1126   child_socket 
= GSocket_WaitConnection(m_socket
); 
1129     GSocket_SetNonBlocking(m_socket
, 0); 
1134   sock
.m_type 
= wxSOCKET_BASE
; 
1135   sock
.m_socket 
= child_socket
; 
1136   sock
.m_connected 
= TRUE
; 
1138   GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout 
* 1000); 
1139   GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
1140                                      GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
, 
1141                                      wx_socket_callback
, (char *)&sock
); 
1146 wxSocketBase 
*wxSocketServer::Accept(bool wait
) 
1148   wxSocketBase
* sock 
= new wxSocketBase(); 
1150   sock
->SetFlags(m_flags
); 
1152   if (!AcceptWith(*sock
, wait
)) 
1161 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
) 
1163   return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
); 
1166 // ========================================================================== 
1168 // ========================================================================== 
1170 // -------------------------------------------------------------------------- 
1172 // -------------------------------------------------------------------------- 
1174 wxSocketClient::wxSocketClient(wxSocketFlags flags
) 
1175               : wxSocketBase(flags
, wxSOCKET_CLIENT
) 
1179 wxSocketClient::~wxSocketClient() 
1183 // -------------------------------------------------------------------------- 
1185 // -------------------------------------------------------------------------- 
1187 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
) 
1193     // Shutdown and destroy the socket 
1195     GSocket_destroy(m_socket
); 
1198   m_socket 
= GSocket_new(); 
1199   m_connected 
= FALSE
; 
1200   m_establishing 
= FALSE
; 
1205   GSocket_SetTimeout(m_socket
, m_timeout 
* 1000); 
1206   GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
1207                                 GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
, 
1208                                 wx_socket_callback
, (char *)this); 
1210   // If wait == FALSE, then the call should be nonblocking. 
1211   // When we are finished, we put the socket to blocking mode 
1215     GSocket_SetNonBlocking(m_socket
, 1); 
1217   GSocket_SetPeer(m_socket
, addr_man
.GetAddress()); 
1218   err 
= GSocket_Connect(m_socket
, GSOCK_STREAMED
); 
1221     GSocket_SetNonBlocking(m_socket
, 0); 
1223   if (err 
!= GSOCK_NOERROR
) 
1225     if (err 
== GSOCK_WOULDBLOCK
) 
1226       m_establishing 
= TRUE
; 
1235 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
) 
1237   if (m_connected
)                      // Already connected 
1240   if (!m_establishing 
|| !m_socket
)     // No connection in progress 
1243   return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG 
| 
1247 // ========================================================================== 
1249 // ========================================================================== 
1251 /* NOTE: experimental stuff - might change */ 
1253 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
, 
1254                                     wxSocketFlags flags 
) 
1255                 : wxSocketBase( flags
, wxSOCKET_DATAGRAM 
) 
1257   // Create the socket 
1258   m_socket 
= GSocket_new(); 
1263   // Setup the socket as non connection oriented 
1264   GSocket_SetLocal(m_socket
, addr
.GetAddress()); 
1265   if( GSocket_SetNonOriented(m_socket
) != GSOCK_NOERROR 
) 
1267     GSocket_destroy(m_socket
); 
1272   // Initialize all stuff 
1273   m_connected 
= FALSE
; 
1274   m_establishing 
= FALSE
; 
1275   GSocket_SetTimeout( m_socket
, m_timeout 
); 
1276   GSocket_SetCallback( m_socket
, GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
1277                                  GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
, 
1278                                  wx_socket_callback
, (char*)this ); 
1282 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
, 
1291 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
, 
1295     GSocket_SetPeer(m_socket
, addr
.GetAddress()); 
1300 // ========================================================================== 
1302 // ========================================================================== 
1304 class WXDLLEXPORT wxSocketModule 
: public wxModule
 
1307     virtual bool OnInit() 
1309         // wxSocketBase will call GSocket_Init() itself when/if needed 
1313     virtual void OnExit() 
1315         if ( wxSocketBase::IsInitialized() ) 
1316             wxSocketBase::Shutdown(); 
1320     DECLARE_DYNAMIC_CLASS(wxSocketModule
) 
1323 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)