1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:       src/common/socket.cpp 
   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:    wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ========================================================================== 
  14 // ========================================================================== 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  25 #include "wx/socket.h" 
  28     #include "wx/object.h" 
  29     #include "wx/string.h" 
  36 #include "wx/apptrait.h" 
  39 #include "wx/module.h" 
  41 #include "wx/sckaddr.h" 
  42 #include "wx/datetime.h" 
  44 // DLL options compatibility check: 
  46 WX_CHECK_BUILD_OPTIONS("wxNet") 
  48 // -------------------------------------------------------------------------- 
  49 // macros and constants 
  50 // -------------------------------------------------------------------------- 
  53 #define MAX_DISCARD_SIZE (10 * 1024) 
  55 // what to do within waits: we have 2 cases: from the main thread itself we 
  56 // have to call wxYield() to let the events (including the GUI events and the 
  57 // low-level (not wxWidgets) events from GSocket) be processed. From another 
  58 // thread it is enough to just call wxThread::Yield() which will give away the 
  59 // rest of our time slice: the explanation is that the events will be processed 
  60 // by the main thread anyhow, without calling wxYield(), but we don't want to 
  61 // eat the CPU time uselessly while sitting in the loop waiting for the data 
  63     #define PROCESS_EVENTS()        \ 
  65         if ( wxThread::IsMain() )   \ 
  70 #else // !wxUSE_THREADS 
  71     #define PROCESS_EVENTS() wxYield() 
  72 #endif // wxUSE_THREADS/!wxUSE_THREADS 
  74 #define wxTRACE_Socket _T("wxSocket") 
  76 // -------------------------------------------------------------------------- 
  78 // -------------------------------------------------------------------------- 
  80 IMPLEMENT_CLASS(wxSocketBase
, wxObject
) 
  81 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
) 
  82 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
) 
  83 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
) 
  84 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
) 
  86 // -------------------------------------------------------------------------- 
  88 // -------------------------------------------------------------------------- 
  90 class wxSocketState 
: public wxObject
 
  93   wxSocketFlags            m_flags
; 
  94   wxSocketEventFlags       m_eventmask
; 
  99   wxSocketState() : wxObject() {} 
 101   DECLARE_NO_COPY_CLASS(wxSocketState
) 
 104 // ========================================================================== 
 106 // ========================================================================== 
 108 // -------------------------------------------------------------------------- 
 109 // Initialization and shutdown 
 110 // -------------------------------------------------------------------------- 
 112 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses 
 113 //           to m_countInit with a crit section 
 114 size_t wxSocketBase::m_countInit 
= 0; 
 116 bool wxSocketBase::IsInitialized() 
 118     return m_countInit 
> 0; 
 121 bool wxSocketBase::Initialize() 
 123     if ( !m_countInit
++ ) 
 126             Details: Initialize() creates a hidden window as a sink for socket 
 127             events, such as 'read completed'. wxMSW has only one message loop 
 128             for the main thread. If Initialize is called in a secondary thread, 
 129             the socket window will be created for the secondary thread, but 
 130             since there is no message loop on this thread, it will never 
 131             receive events and all socket operations will time out. 
 132             BTW, the main thread must not be stopped using sleep or block 
 133             on a semaphore (a bad idea in any case) or socket operations 
 136             On the Mac side, Initialize() stores a pointer to the CFRunLoop for 
 137             the main thread. Because secondary threads do not have run loops, 
 138             adding event notifications to the "Current" loop would have no 
 139             effect at all, events would never fire. 
 141         wxASSERT_MSG( wxIsMainThread(), 
 142             wxT("Call wxSocketBase::Initialize() from the main thread first!")); 
 144         wxAppTraits 
*traits 
= wxAppConsole::GetInstance() ? 
 145                               wxAppConsole::GetInstance()->GetTraits() : NULL
; 
 146         GSocketGUIFunctionsTable 
*functions 
= 
 147             traits 
? traits
->GetSocketGUIFunctionsTable() : NULL
; 
 148         GSocket_SetGUIFunctions(functions
); 
 150         if ( !GSocket_Init() ) 
 161 void wxSocketBase::Shutdown() 
 163     // we should be initialized 
 164     wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") ); 
 165     if ( --m_countInit 
== 0 ) 
 171 // -------------------------------------------------------------------------- 
 173 // -------------------------------------------------------------------------- 
 175 void wxSocketBase::Init() 
 178   m_type         
= wxSOCKET_UNINIT
; 
 189   m_beingDeleted 
= false; 
 203   if ( !IsInitialized() ) 
 205       // this Initialize() will be undone by wxSocketModule::OnExit(), all the 
 206       // other calls to it should be matched by a call to Shutdown() 
 211 wxSocketBase::wxSocketBase() 
 216 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
) 
 224 wxSocketBase::~wxSocketBase() 
 226   // Just in case the app called Destroy() *and* then deleted 
 227   // the socket immediately: don't leave dangling pointers. 
 228   wxAppTraits 
*traits 
= wxTheApp 
? wxTheApp
->GetTraits() : NULL
; 
 230       traits
->RemoveFromPendingDelete(this); 
 232   // Shutdown and close the socket 
 236   // Destroy the GSocket object 
 240   // Free the pushback buffer 
 245 bool wxSocketBase::Destroy() 
 247   // Delayed destruction: the socket will be deleted during the next 
 248   // idle loop iteration. This ensures that all pending events have 
 250   m_beingDeleted 
= true; 
 252   // Shutdown and close the socket 
 255   // Supress events from now on 
 258   // schedule this object for deletion 
 259   wxAppTraits 
*traits 
= wxTheApp 
? wxTheApp
->GetTraits() : NULL
; 
 262       // let the traits object decide what to do with us 
 263       traits
->ScheduleForDestroy(this); 
 265   else // no app or no traits 
 267       // in wxBase we might have no app object at all, don't leak memory 
 274 // -------------------------------------------------------------------------- 
 276 // -------------------------------------------------------------------------- 
 278 // The following IO operations update m_error and m_lcount: 
 279 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard} 
 281 // TODO: Should Connect, Accept and AcceptWith update m_error? 
 283 bool wxSocketBase::Close() 
 285   // Interrupt pending waits 
 291     m_socket
->UnsetCallback(GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
 292                                     GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
); 
 294     // Shutdown the connection 
 295     m_socket
->Shutdown(); 
 299   m_establishing 
= false; 
 303 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
) 
 308   m_lcount 
= _Read(buffer
, nbytes
); 
 310   // If in wxSOCKET_WAITALL mode, all bytes should have been read. 
 311   if (m_flags 
& wxSOCKET_WAITALL
) 
 312     m_error 
= (m_lcount 
!= nbytes
); 
 314     m_error 
= (m_lcount 
== 0); 
 316   // Allow read events from now on 
 322 wxUint32 
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
) 
 326   // Try the pushback buffer first 
 327   total 
= GetPushback(buffer
, nbytes
, false); 
 329   buffer  
= (char *)buffer 
+ total
; 
 331   // Return now in one of the following cases: 
 332   // - the socket is invalid, 
 333   // - we got all the data, 
 334   // - we got *some* data and we are not using wxSOCKET_WAITALL. 
 337        ((total 
!= 0) && !(m_flags 
& wxSOCKET_WAITALL
)) ) 
 340   // Possible combinations (they are checked in this order) 
 342   // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK) 
 347   if (m_flags 
& wxSOCKET_NOWAIT
) 
 349     m_socket
->SetNonBlocking(1); 
 350     ret 
= m_socket
->Read((char *)buffer
, nbytes
); 
 351     m_socket
->SetNonBlocking(0); 
 362       if ( !(m_flags 
& wxSOCKET_BLOCK
) && !WaitForRead() ) 
 365       ret 
= m_socket
->Read((char *)buffer
, nbytes
); 
 371         buffer  
= (char *)buffer 
+ ret
; 
 374       // If we got here and wxSOCKET_WAITALL is not set, we can leave 
 375       // now. Otherwise, wait until we recv all the data or until there 
 378       more 
= (ret 
> 0 && nbytes 
> 0 && (m_flags 
& wxSOCKET_WAITALL
)); 
 385 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
) 
 387   wxUint32 len
, len2
, sig
, total
; 
 392     unsigned char sig
[4]; 
 393     unsigned char len
[4]; 
 402   SetFlags((m_flags 
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
); 
 404   if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
)) 
 407   sig 
= (wxUint32
)msg
.sig
[0]; 
 408   sig 
|= (wxUint32
)(msg
.sig
[1] << 8); 
 409   sig 
|= (wxUint32
)(msg
.sig
[2] << 16); 
 410   sig 
|= (wxUint32
)(msg
.sig
[3] << 24); 
 412   if (sig 
!= 0xfeeddead) 
 414     wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); 
 418   len 
= (wxUint32
)msg
.len
[0]; 
 419   len 
|= (wxUint32
)(msg
.len
[1] << 8); 
 420   len 
|= (wxUint32
)(msg
.len
[2] << 16); 
 421   len 
|= (wxUint32
)(msg
.len
[3] << 24); 
 431   // Don't attemp to read if the msg was zero bytes long. 
 434     total 
= _Read(buffer
, len
); 
 441     char *discard_buffer 
= new char[MAX_DISCARD_SIZE
]; 
 444     // NOTE: discarded bytes don't add to m_lcount. 
 447       discard_len 
= ((len2 
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE 
: len2
); 
 448       discard_len 
= _Read(discard_buffer
, (wxUint32
)discard_len
); 
 449       len2 
-= (wxUint32
)discard_len
; 
 451     while ((discard_len 
> 0) && len2
); 
 453     delete [] discard_buffer
; 
 458   if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
)) 
 461   sig 
= (wxUint32
)msg
.sig
[0]; 
 462   sig 
|= (wxUint32
)(msg
.sig
[1] << 8); 
 463   sig 
|= (wxUint32
)(msg
.sig
[2] << 16); 
 464   sig 
|= (wxUint32
)(msg
.sig
[3] << 24); 
 466   if (sig 
!= 0xdeadfeed) 
 468     wxLogWarning(_("wxSocket: invalid signature in ReadMsg.")); 
 484 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
) 
 489   m_lcount 
= _Read(buffer
, nbytes
); 
 490   Pushback(buffer
, m_lcount
); 
 492   // If in wxSOCKET_WAITALL mode, all bytes should have been read. 
 493   if (m_flags 
& wxSOCKET_WAITALL
) 
 494     m_error 
= (m_lcount 
!= nbytes
); 
 496     m_error 
= (m_lcount 
== 0); 
 498   // Allow read events again 
 504 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
) 
 509   m_lcount 
= _Write(buffer
, nbytes
); 
 511   // If in wxSOCKET_WAITALL mode, all bytes should have been written. 
 512   if (m_flags 
& wxSOCKET_WAITALL
) 
 513     m_error 
= (m_lcount 
!= nbytes
); 
 515     m_error 
= (m_lcount 
== 0); 
 517   // Allow write events again 
 523 wxUint32 
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
) 
 527   // If the socket is invalid or parameters are ill, return immediately 
 528   if (!m_socket 
|| !buffer 
|| !nbytes
) 
 531   // Possible combinations (they are checked in this order) 
 533   // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK) 
 538   if (m_flags 
& wxSOCKET_NOWAIT
) 
 540     m_socket
->SetNonBlocking(1); 
 541     ret 
= m_socket
->Write((const char *)buffer
, nbytes
); 
 542     m_socket
->SetNonBlocking(0); 
 553       if ( !(m_flags 
& wxSOCKET_BLOCK
) && !WaitForWrite() ) 
 556       ret 
= m_socket
->Write((const char *)buffer
, nbytes
); 
 562         buffer  
= (const char *)buffer 
+ ret
; 
 565       // If we got here and wxSOCKET_WAITALL is not set, we can leave 
 566       // now. Otherwise, wait until we send all the data or until there 
 569       more 
= (ret 
> 0 && nbytes 
> 0 && (m_flags 
& wxSOCKET_WAITALL
)); 
 576 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
) 
 582     unsigned char sig
[4]; 
 583     unsigned char len
[4]; 
 591   SetFlags((m_flags 
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
); 
 593   msg
.sig
[0] = (unsigned char) 0xad; 
 594   msg
.sig
[1] = (unsigned char) 0xde; 
 595   msg
.sig
[2] = (unsigned char) 0xed; 
 596   msg
.sig
[3] = (unsigned char) 0xfe; 
 598   msg
.len
[0] = (unsigned char) (nbytes 
& 0xff); 
 599   msg
.len
[1] = (unsigned char) ((nbytes 
>> 8) & 0xff); 
 600   msg
.len
[2] = (unsigned char) ((nbytes 
>> 16) & 0xff); 
 601   msg
.len
[3] = (unsigned char) ((nbytes 
>> 24) & 0xff); 
 603   if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
)) 
 606   total 
= _Write(buffer
, nbytes
); 
 611   msg
.sig
[0] = (unsigned char) 0xed; 
 612   msg
.sig
[1] = (unsigned char) 0xfe; 
 613   msg
.sig
[2] = (unsigned char) 0xad; 
 614   msg
.sig
[3] = (unsigned char) 0xde; 
 615   msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0; 
 617   if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
)) 
 631 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
) 
 634     Pushback(buffer
, nbytes
); 
 642 wxSocketBase
& wxSocketBase::Discard() 
 644   char *buffer 
= new char[MAX_DISCARD_SIZE
]; 
 651   SetFlags(wxSOCKET_NOWAIT
); 
 655     ret 
= _Read(buffer
, MAX_DISCARD_SIZE
); 
 658   while (ret 
== MAX_DISCARD_SIZE
); 
 664   // Allow read events again 
 670 // -------------------------------------------------------------------------- 
 672 // -------------------------------------------------------------------------- 
 674 // All Wait functions poll the socket using GSocket_Select() to 
 675 // check for the specified combination of conditions, until one 
 676 // of these conditions become true, an error occurs, or the 
 677 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so 
 678 // this won't block the GUI. 
 680 bool wxSocketBase::_Wait(long seconds
, 
 682                          wxSocketEventFlags flags
) 
 684   GSocketEventFlags result
; 
 687   // Set this to true to interrupt ongoing waits 
 690   // Check for valid socket 
 694   // Check for valid timeout value. 
 696     timeout 
= seconds 
* 1000 + milliseconds
; 
 698     timeout 
= m_timeout 
* 1000; 
 700   bool has_event_loop 
= wxTheApp
->GetTraits() ? (wxTheApp
->GetTraits()->GetSocketGUIFunctionsTable() ? true : false) : false; 
 702   // Wait in an active polling loop. 
 704   // NOTE: We duplicate some of the code in OnRequest, but this doesn't 
 705   //   hurt. It has to be here because the (GSocket) event might arrive 
 706   //   a bit delayed, and it has to be in OnRequest as well because we 
 707   //   don't know whether the Wait functions are being used. 
 709   // Do this at least once (important if timeout == 0, when 
 710   // we are just polling). Also, if just polling, do not yield. 
 712   wxDateTime current_time 
= wxDateTime::UNow(); 
 713   unsigned int time_limit 
= (current_time
.GetTicks() * 1000) + current_time
.GetMillisecond() + timeout
; 
 715   bool valid_result 
= false; 
 719     // This is used to avoid a busy loop on wxBase - having a select 
 720     // timeout of 50 ms per iteration should be enough. 
 722       m_socket
->SetTimeout(50); 
 724       m_socket
->SetTimeout(timeout
); 
 729     result 
= m_socket
->Select(flags 
| GSOCK_LOST_FLAG
); 
 731     // Incoming connection (server) or connection established (client) 
 732     if (result 
& GSOCK_CONNECTION_FLAG
) 
 735       m_establishing 
= false; 
 740     // Data available or output buffer ready 
 741     if ((result 
& GSOCK_INPUT_FLAG
) || (result 
& GSOCK_OUTPUT_FLAG
)) 
 748     if (result 
& GSOCK_LOST_FLAG
) 
 751       m_establishing 
= false; 
 752       valid_result 
= ((flags 
& GSOCK_LOST_FLAG
) != 0); 
 757     current_time 
= wxDateTime::UNow(); 
 758     int time_left 
= time_limit 
- ((current_time
.GetTicks() * 1000) + current_time
.GetMillisecond()); 
 759     if ((!timeout
) || (time_left 
<= 0) || (m_interrupt
)) 
 769         // If there's less than 50 ms left, just call select with that timeout. 
 771           m_socket
->SetTimeout(time_left
); 
 776   // Set timeout back to original value (we overwrote it for polling) 
 778     m_socket
->SetTimeout(m_timeout
*1000); 
 783 bool wxSocketBase::Wait(long seconds
, long milliseconds
) 
 785     return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG 
| 
 787                                         GSOCK_CONNECTION_FLAG 
| 
 791 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
) 
 793   // Check pushback buffer before entering _Wait 
 797   // Note that GSOCK_INPUT_LOST has to be explicitly passed to 
 798   // _Wait because of the semantics of WaitForRead: a return 
 799   // value of true means that a GSocket_Read call will return 
 800   // immediately, not that there is actually data to read. 
 802   return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG 
| 
 807 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
) 
 809     return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
); 
 812 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
) 
 814     return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
); 
 817 // -------------------------------------------------------------------------- 
 819 // -------------------------------------------------------------------------- 
 822 // Get local or peer address 
 825 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const 
 832   peer 
= m_socket
->GetPeer(); 
 834     // copying a null address would just trigger an assert anyway 
 839   addr_man
.SetAddress(peer
); 
 840   GAddress_destroy(peer
); 
 845 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const 
 852     local 
= m_socket
->GetLocal(); 
 853     addr_man
.SetAddress(local
); 
 854     GAddress_destroy(local
); 
 860 // Save and restore socket state 
 863 void wxSocketBase::SaveState() 
 865     wxSocketState 
*state
; 
 867     state 
= new wxSocketState(); 
 869     state
->m_flags      
= m_flags
; 
 870     state
->m_notify     
= m_notify
; 
 871     state
->m_eventmask  
= m_eventmask
; 
 872     state
->m_clientData 
= m_clientData
; 
 874     m_states
.Append(state
); 
 877 void wxSocketBase::RestoreState() 
 879     wxList::compatibility_iterator node
; 
 880     wxSocketState 
*state
; 
 882     node 
= m_states
.GetLast(); 
 886     state 
= (wxSocketState 
*)node
->GetData(); 
 888     m_flags      
= state
->m_flags
; 
 889     m_notify     
= state
->m_notify
; 
 890     m_eventmask  
= state
->m_eventmask
; 
 891     m_clientData 
= state
->m_clientData
; 
 893     m_states
.Erase(node
); 
 901 void wxSocketBase::SetTimeout(long seconds
) 
 906         m_socket
->SetTimeout(m_timeout 
* 1000); 
 909 void wxSocketBase::SetFlags(wxSocketFlags flags
) 
 915 // -------------------------------------------------------------------------- 
 917 // -------------------------------------------------------------------------- 
 919 // A note on how events are processed, which is probably the most 
 920 // difficult thing to get working right while keeping the same API 
 921 // and functionality for all platforms. 
 923 // When GSocket detects an event, it calls wx_socket_callback, which in 
 924 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket 
 925 // object. OnRequest does some housekeeping, and if the event is to be 
 926 // propagated to the user, it creates a new wxSocketEvent object and 
 927 // posts it. The event is not processed immediately, but delayed with 
 928 // AddPendingEvent instead. This is necessary in order to decouple the 
 929 // event processing from wx_socket_callback; otherwise, subsequent IO 
 930 // calls made from the user event handler would fail, as gtk callbacks 
 931 // are not reentrant. 
 933 // Note that, unlike events, user callbacks (now deprecated) are _not_ 
 934 // decoupled from wx_socket_callback and thus they suffer from a variety 
 935 // of problems. Avoid them where possible and use events instead. 
 938 void LINKAGEMODE 
wx_socket_callback(GSocket 
* WXUNUSED(socket
), 
 939                                     GSocketEvent notification
, 
 942     wxSocketBase 
*sckobj 
= (wxSocketBase 
*)cdata
; 
 944     sckobj
->OnRequest((wxSocketNotify
) notification
); 
 947 void wxSocketBase::OnRequest(wxSocketNotify notification
) 
 949   // NOTE: We duplicate some of the code in _Wait, but this doesn't 
 950   //   hurt. It has to be here because the (GSocket) event might arrive 
 951   //   a bit delayed, and it has to be in _Wait as well because we don't 
 952   //   know whether the Wait functions are being used. 
 956     case wxSOCKET_CONNECTION
: 
 957       m_establishing 
= false; 
 961     // If we are in the middle of a R/W operation, do not 
 962     // propagate events to users. Also, filter 'late' events 
 963     // which are no longer valid. 
 966       if (m_reading 
|| !m_socket
->Select(GSOCK_INPUT_FLAG
)) 
 970     case wxSOCKET_OUTPUT
: 
 971       if (m_writing 
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
)) 
 977       m_establishing 
= false; 
 984   // Schedule the event 
 986   wxSocketEventFlags flag 
= 0; 
 988   switch (notification
) 
 990     case GSOCK_INPUT
:      flag 
= GSOCK_INPUT_FLAG
; break; 
 991     case GSOCK_OUTPUT
:     flag 
= GSOCK_OUTPUT_FLAG
; break; 
 992     case GSOCK_CONNECTION
: flag 
= GSOCK_CONNECTION_FLAG
; break; 
 993     case GSOCK_LOST
:       flag 
= GSOCK_LOST_FLAG
; break; 
 995       wxLogWarning(_("wxSocket: unknown event!.")); 
 999   if (((m_eventmask 
& flag
) == flag
) && m_notify
) 
1003       wxSocketEvent 
event(m_id
); 
1004       event
.m_event      
= notification
; 
1005       event
.m_clientData 
= m_clientData
; 
1006       event
.SetEventObject(this); 
1008       m_handler
->AddPendingEvent(event
); 
1013 void wxSocketBase::Notify(bool notify
) 
1018 void wxSocketBase::SetNotify(wxSocketEventFlags flags
) 
1020     m_eventmask 
= flags
; 
1023 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
) 
1025     m_handler 
= &handler
; 
1029 // -------------------------------------------------------------------------- 
1031 // -------------------------------------------------------------------------- 
1033 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
) 
1037   if (m_unread 
== NULL
) 
1038     m_unread 
= malloc(size
); 
1043     tmp 
= malloc(m_unrd_size 
+ size
); 
1044     memcpy((char *)tmp 
+ size
, m_unread
, m_unrd_size
); 
1050   m_unrd_size 
+= size
; 
1052   memcpy(m_unread
, buffer
, size
); 
1055 wxUint32 
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
) 
1060   if (size 
> (m_unrd_size
-m_unrd_cur
)) 
1061     size 
= m_unrd_size
-m_unrd_cur
; 
1063   memcpy(buffer
, (char *)m_unread 
+ m_unrd_cur
, size
); 
1068     if (m_unrd_size 
== m_unrd_cur
) 
1081 // ========================================================================== 
1083 // ========================================================================== 
1085 // -------------------------------------------------------------------------- 
1087 // -------------------------------------------------------------------------- 
1089 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
, 
1090                                wxSocketFlags flags
) 
1091               : wxSocketBase(flags
, wxSOCKET_SERVER
) 
1093     wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") ); 
1095     m_socket 
= GSocket_new(); 
1099         wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") ); 
1103         // Setup the socket as server 
1105     m_socket
->SetLocal(addr_man
.GetAddress()); 
1107     if (GetFlags() & wxSOCKET_REUSEADDR
) { 
1108         m_socket
->SetReusable(); 
1111     if (m_socket
->SetServer() != GSOCK_NOERROR
) 
1116         wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") ); 
1120     m_socket
->SetTimeout(m_timeout 
* 1000); 
1121     m_socket
->SetCallback(GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
1122                                   GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
, 
1123                                   wx_socket_callback
, (char *)this); 
1126 // -------------------------------------------------------------------------- 
1128 // -------------------------------------------------------------------------- 
1130 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
) 
1132   GSocket 
*child_socket
; 
1137   // If wait == false, then the call should be nonblocking. 
1138   // When we are finished, we put the socket to blocking mode 
1142     m_socket
->SetNonBlocking(1); 
1144   child_socket 
= m_socket
->WaitConnection(); 
1147     m_socket
->SetNonBlocking(0); 
1152   sock
.m_type 
= wxSOCKET_BASE
; 
1153   sock
.m_socket 
= child_socket
; 
1154   sock
.m_connected 
= true; 
1156   sock
.m_socket
->SetTimeout(sock
.m_timeout 
* 1000); 
1157   sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
1158                                      GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
, 
1159                                      wx_socket_callback
, (char *)&sock
); 
1164 wxSocketBase 
*wxSocketServer::Accept(bool wait
) 
1166   wxSocketBase
* sock 
= new wxSocketBase(); 
1168   sock
->SetFlags(m_flags
); 
1170   if (!AcceptWith(*sock
, wait
)) 
1179 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
) 
1181     return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
); 
1184 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
) 
1186     wxASSERT_MSG( m_socket
, _T("Socket not initialised") ); 
1188     if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
) 
1196 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
, 
1199     wxASSERT_MSG( m_socket
, _T("Socket not initialised") ); 
1201     if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
) 
1209 bool wxSocketBase::SetLocal(wxIPV4address
& local
) 
1211   GAddress
* la 
= local
.GetAddress(); 
1213   // If the address is valid, save it for use when we call Connect 
1214   if (la 
&& la
->m_addr
) 
1216     m_localAddress 
= local
; 
1224 // ========================================================================== 
1226 // ========================================================================== 
1228 // -------------------------------------------------------------------------- 
1230 // -------------------------------------------------------------------------- 
1232 wxSocketClient::wxSocketClient(wxSocketFlags flags
) 
1233               : wxSocketBase(flags
, wxSOCKET_CLIENT
) 
1237 wxSocketClient::~wxSocketClient() 
1241 // -------------------------------------------------------------------------- 
1243 // -------------------------------------------------------------------------- 
1245 bool wxSocketClient::DoConnect(wxSockAddress
& addr_man
, wxSockAddress
* local
, bool wait
) 
1251     // Shutdown and destroy the socket 
1256   m_socket 
= GSocket_new(); 
1257   m_connected 
= false; 
1258   m_establishing 
= false; 
1263   m_socket
->SetTimeout(m_timeout 
* 1000); 
1264   m_socket
->SetCallback(GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
1265                                 GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
, 
1266                                 wx_socket_callback
, (char *)this); 
1268   // If wait == false, then the call should be nonblocking. 
1269   // When we are finished, we put the socket to blocking mode 
1273     m_socket
->SetNonBlocking(1); 
1275   // Reuse makes sense for clients too, if we are trying to rebind to the same port 
1276   if (GetFlags() & wxSOCKET_REUSEADDR
) 
1278     m_socket
->SetReusable(); 
1281   // If no local address was passed and one has been set, use the one that was Set 
1282   if (!local 
&& m_localAddress
.GetAddress()) 
1284     local 
= &m_localAddress
; 
1287   // Bind to the local IP address and port, when provided 
1290     GAddress
* la 
= local
->GetAddress(); 
1292     if (la 
&& la
->m_addr
) 
1293       m_socket
->SetLocal(la
); 
1296   m_socket
->SetPeer(addr_man
.GetAddress()); 
1297   err 
= m_socket
->Connect(GSOCK_STREAMED
); 
1300     m_socket
->SetNonBlocking(0); 
1302   if (err 
!= GSOCK_NOERROR
) 
1304     if (err 
== GSOCK_WOULDBLOCK
) 
1305       m_establishing 
= true; 
1314 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
) 
1316     return (DoConnect(addr_man
, NULL
, wait
)); 
1319 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, wxSockAddress
& local
, bool wait
) 
1321     return (DoConnect(addr_man
, &local
, wait
)); 
1324 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
) 
1326     if (m_connected
)                      // Already connected 
1329     if (!m_establishing 
|| !m_socket
)     // No connection in progress 
1332     return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG 
| 
1336 // ========================================================================== 
1338 // ========================================================================== 
1340 /* NOTE: experimental stuff - might change */ 
1342 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
, 
1343                                     wxSocketFlags flags 
) 
1344                 : wxSocketBase( flags
, wxSOCKET_DATAGRAM 
) 
1346     // Create the socket 
1347     m_socket 
= GSocket_new(); 
1351         wxFAIL_MSG( _T("datagram socket not new'd") ); 
1354     // Setup the socket as non connection oriented 
1355     m_socket
->SetLocal(addr
.GetAddress()); 
1356     if( m_socket
->SetNonOriented() != GSOCK_NOERROR 
) 
1363     // Initialize all stuff 
1364     m_connected 
= false; 
1365     m_establishing 
= false; 
1366     m_socket
->SetTimeout( m_timeout 
); 
1367     m_socket
->SetCallback( GSOCK_INPUT_FLAG 
| GSOCK_OUTPUT_FLAG 
| 
1368                            GSOCK_LOST_FLAG 
| GSOCK_CONNECTION_FLAG
, 
1369                            wx_socket_callback
, (char*)this ); 
1372 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
, 
1381 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
, 
1385     wxASSERT_MSG( m_socket
, _T("Socket not initialised") ); 
1387     m_socket
->SetPeer(addr
.GetAddress()); 
1392 // ========================================================================== 
1394 // ========================================================================== 
1396 class wxSocketModule 
: public wxModule
 
1399     virtual bool OnInit() 
1401         // wxSocketBase will call GSocket_Init() itself when/if needed 
1405     virtual void OnExit() 
1407         if ( wxSocketBase::IsInitialized() ) 
1408             wxSocketBase::Shutdown(); 
1412     DECLARE_DYNAMIC_CLASS(wxSocketModule
) 
1415 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)