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 licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ==========================================================================
14 // ==========================================================================
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
26 #include "wx/apptrait.h"
28 #include "wx/object.h"
29 #include "wx/string.h"
32 #include "wx/module.h"
37 #include "wx/sckaddr.h"
38 #include "wx/socket.h"
39 #include "wx/datetime.h"
41 // DLL options compatibility check:
43 WX_CHECK_BUILD_OPTIONS("wxNet")
45 // --------------------------------------------------------------------------
46 // macros and constants
47 // --------------------------------------------------------------------------
50 #define MAX_DISCARD_SIZE (10 * 1024)
52 // what to do within waits: we have 2 cases: from the main thread itself we
53 // have to call wxYield() to let the events (including the GUI events and the
54 // low-level (not wxWidgets) events from GSocket) be processed. From another
55 // thread it is enough to just call wxThread::Yield() which will give away the
56 // rest of our time slice: the explanation is that the events will be processed
57 // by the main thread anyhow, without calling wxYield(), but we don't want to
58 // eat the CPU time uselessly while sitting in the loop waiting for the data
60 #define PROCESS_EVENTS() \
62 if ( wxThread::IsMain() ) \
67 #else // !wxUSE_THREADS
68 #define PROCESS_EVENTS() wxYield()
69 #endif // wxUSE_THREADS/!wxUSE_THREADS
71 #define wxTRACE_Socket _T("wxSocket")
73 // --------------------------------------------------------------------------
75 // --------------------------------------------------------------------------
77 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
78 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
79 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
80 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
81 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
83 // --------------------------------------------------------------------------
85 // --------------------------------------------------------------------------
87 class wxSocketState
: public wxObject
90 wxSocketFlags m_flags
;
91 wxSocketEventFlags m_eventmask
;
96 wxSocketState() : wxObject() {}
98 DECLARE_NO_COPY_CLASS(wxSocketState
)
101 // ==========================================================================
103 // ==========================================================================
105 // --------------------------------------------------------------------------
106 // Initialization and shutdown
107 // --------------------------------------------------------------------------
109 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
110 // to m_countInit with a crit section
111 size_t wxSocketBase::m_countInit
= 0;
113 bool wxSocketBase::IsInitialized()
115 return m_countInit
> 0;
118 bool wxSocketBase::Initialize()
120 if ( !m_countInit
++ )
123 Details: Initialize() creates a hidden window as a sink for socket
124 events, such as 'read completed'. wxMSW has only one message loop
125 for the main thread. If Initialize is called in a secondary thread,
126 the socket window will be created for the secondary thread, but
127 since there is no message loop on this thread, it will never
128 receive events and all socket operations will time out.
129 BTW, the main thread must not be stopped using sleep or block
130 on a semaphore (a bad idea in any case) or socket operations
133 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
134 the main thread. Because secondary threads do not have run loops,
135 adding event notifications to the "Current" loop would have no
136 effect at all, events would never fire.
138 wxASSERT_MSG( wxIsMainThread(),
139 wxT("Call wxSocketBase::Initialize() from the main thread first!"));
141 wxAppTraits
*traits
= wxAppConsole::GetInstance() ?
142 wxAppConsole::GetInstance()->GetTraits() : NULL
;
143 GSocketGUIFunctionsTable
*functions
=
144 traits
? traits
->GetSocketGUIFunctionsTable() : NULL
;
145 GSocket_SetGUIFunctions(functions
);
147 if ( !GSocket_Init() )
158 void wxSocketBase::Shutdown()
160 // we should be initialized
161 wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") );
162 if ( --m_countInit
== 0 )
168 // --------------------------------------------------------------------------
170 // --------------------------------------------------------------------------
172 void wxSocketBase::Init()
175 m_type
= wxSOCKET_UNINIT
;
186 m_beingDeleted
= false;
200 if ( !IsInitialized() )
202 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
203 // other calls to it should be matched by a call to Shutdown()
208 wxSocketBase::wxSocketBase()
213 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
221 wxSocketBase::~wxSocketBase()
223 // Just in case the app called Destroy() *and* then deleted
224 // the socket immediately: don't leave dangling pointers.
225 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
227 traits
->RemoveFromPendingDelete(this);
229 // Shutdown and close the socket
233 // Destroy the GSocket object
237 // Free the pushback buffer
242 bool wxSocketBase::Destroy()
244 // Delayed destruction: the socket will be deleted during the next
245 // idle loop iteration. This ensures that all pending events have
247 m_beingDeleted
= true;
249 // Shutdown and close the socket
252 // Supress events from now on
255 // schedule this object for deletion
256 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
259 // let the traits object decide what to do with us
260 traits
->ScheduleForDestroy(this);
262 else // no app or no traits
264 // in wxBase we might have no app object at all, don't leak memory
271 // --------------------------------------------------------------------------
273 // --------------------------------------------------------------------------
275 // The following IO operations update m_error and m_lcount:
276 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
278 // TODO: Should Connect, Accept and AcceptWith update m_error?
280 bool wxSocketBase::Close()
282 // Interrupt pending waits
288 m_socket
->UnsetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
289 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
291 // Shutdown the connection
292 m_socket
->Shutdown();
296 m_establishing
= false;
300 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
305 m_lcount
= _Read(buffer
, nbytes
);
307 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
308 if (m_flags
& wxSOCKET_WAITALL
)
309 m_error
= (m_lcount
!= nbytes
);
311 m_error
= (m_lcount
== 0);
313 // Allow read events from now on
319 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
323 // Try the pushback buffer first
324 total
= GetPushback(buffer
, nbytes
, false);
326 buffer
= (char *)buffer
+ total
;
328 // Return now in one of the following cases:
329 // - the socket is invalid,
330 // - we got all the data,
331 // - we got *some* data and we are not using wxSOCKET_WAITALL.
334 ((total
!= 0) && !(m_flags
& wxSOCKET_WAITALL
)) )
337 // Possible combinations (they are checked in this order)
339 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
344 if (m_flags
& wxSOCKET_NOWAIT
)
346 m_socket
->SetNonBlocking(1);
347 ret
= m_socket
->Read((char *)buffer
, nbytes
);
348 m_socket
->SetNonBlocking(0);
359 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
362 ret
= m_socket
->Read((char *)buffer
, nbytes
);
368 buffer
= (char *)buffer
+ ret
;
371 // If we got here and wxSOCKET_WAITALL is not set, we can leave
372 // now. Otherwise, wait until we recv all the data or until there
375 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
382 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
384 wxUint32 len
, len2
, sig
, total
;
389 unsigned char sig
[4];
390 unsigned char len
[4];
399 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
401 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
404 sig
= (wxUint32
)msg
.sig
[0];
405 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
406 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
407 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
409 if (sig
!= 0xfeeddead)
411 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
415 len
= (wxUint32
)msg
.len
[0];
416 len
|= (wxUint32
)(msg
.len
[1] << 8);
417 len
|= (wxUint32
)(msg
.len
[2] << 16);
418 len
|= (wxUint32
)(msg
.len
[3] << 24);
428 // Don't attemp to read if the msg was zero bytes long.
431 total
= _Read(buffer
, len
);
438 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
441 // NOTE: discarded bytes don't add to m_lcount.
444 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
445 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
446 len2
-= (wxUint32
)discard_len
;
448 while ((discard_len
> 0) && len2
);
450 delete [] discard_buffer
;
455 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
458 sig
= (wxUint32
)msg
.sig
[0];
459 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
460 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
461 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
463 if (sig
!= 0xdeadfeed)
465 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
481 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
486 m_lcount
= _Read(buffer
, nbytes
);
487 Pushback(buffer
, m_lcount
);
489 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
490 if (m_flags
& wxSOCKET_WAITALL
)
491 m_error
= (m_lcount
!= nbytes
);
493 m_error
= (m_lcount
== 0);
495 // Allow read events again
501 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
506 m_lcount
= _Write(buffer
, nbytes
);
508 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
509 if (m_flags
& wxSOCKET_WAITALL
)
510 m_error
= (m_lcount
!= nbytes
);
512 m_error
= (m_lcount
== 0);
514 // Allow write events again
520 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
524 // If the socket is invalid or parameters are ill, return immediately
525 if (!m_socket
|| !buffer
|| !nbytes
)
528 // Possible combinations (they are checked in this order)
530 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
535 if (m_flags
& wxSOCKET_NOWAIT
)
537 m_socket
->SetNonBlocking(1);
538 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
539 m_socket
->SetNonBlocking(0);
550 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
553 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
559 buffer
= (const char *)buffer
+ ret
;
562 // If we got here and wxSOCKET_WAITALL is not set, we can leave
563 // now. Otherwise, wait until we send all the data or until there
566 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
573 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
579 unsigned char sig
[4];
580 unsigned char len
[4];
588 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
590 msg
.sig
[0] = (unsigned char) 0xad;
591 msg
.sig
[1] = (unsigned char) 0xde;
592 msg
.sig
[2] = (unsigned char) 0xed;
593 msg
.sig
[3] = (unsigned char) 0xfe;
595 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
596 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
597 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
598 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
600 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
603 total
= _Write(buffer
, nbytes
);
608 msg
.sig
[0] = (unsigned char) 0xed;
609 msg
.sig
[1] = (unsigned char) 0xfe;
610 msg
.sig
[2] = (unsigned char) 0xad;
611 msg
.sig
[3] = (unsigned char) 0xde;
612 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
614 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
628 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
631 Pushback(buffer
, nbytes
);
639 wxSocketBase
& wxSocketBase::Discard()
641 char *buffer
= new char[MAX_DISCARD_SIZE
];
648 SetFlags(wxSOCKET_NOWAIT
);
652 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
655 while (ret
== MAX_DISCARD_SIZE
);
661 // Allow read events again
667 // --------------------------------------------------------------------------
669 // --------------------------------------------------------------------------
671 // All Wait functions poll the socket using GSocket_Select() to
672 // check for the specified combination of conditions, until one
673 // of these conditions become true, an error occurs, or the
674 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
675 // this won't block the GUI.
677 bool wxSocketBase::_Wait(long seconds
,
679 wxSocketEventFlags flags
)
681 GSocketEventFlags result
;
684 // Set this to true to interrupt ongoing waits
687 // Check for valid socket
691 // Check for valid timeout value.
693 timeout
= seconds
* 1000 + milliseconds
;
695 timeout
= m_timeout
* 1000;
697 // Wait in an active polling loop.
699 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
700 // hurt. It has to be here because the (GSocket) event might arrive
701 // a bit delayed, and it has to be in OnRequest as well because we
702 // don't know whether the Wait functions are being used.
704 // Do this at least once (important if timeout == 0, when
705 // we are just polling). Also, if just polling, do not yield.
707 wxDateTime current_time
= wxDateTime::UNow();
708 unsigned int time_limit
= (current_time
.GetTicks() * 1000) + current_time
.GetMillisecond() + timeout
;
710 bool valid_result
= false;
712 #if !defined(wxUSE_GUI) || !wxUSE_GUI
713 // This is used to avoid a busy loop on wxBase - having a select
714 // timeout of 50 ms per iteration should be enough.
716 m_socket
->SetTimeout(50);
718 m_socket
->SetTimeout(timeout
);
723 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
725 // Incoming connection (server) or connection established (client)
726 if (result
& GSOCK_CONNECTION_FLAG
)
729 m_establishing
= false;
734 // Data available or output buffer ready
735 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
742 if (result
& GSOCK_LOST_FLAG
)
745 m_establishing
= false;
746 valid_result
= ((flags
& GSOCK_LOST_FLAG
) != 0);
751 current_time
= wxDateTime::UNow();
752 int time_left
= time_limit
- ((current_time
.GetTicks() * 1000) + current_time
.GetMillisecond());
753 if ((!timeout
) || (time_left
<= 0) || (m_interrupt
))
757 #if !defined(wxUSE_GUI) || !wxUSE_GUI
758 // If there's less than 50 ms left, just call select with that timeout.
760 m_socket
->SetTimeout(time_left
);
767 // Set timeout back to original value (we overwrote it for polling)
768 #if !defined(wxUSE_GUI) || !wxUSE_GUI
769 m_socket
->SetTimeout(m_timeout
*1000);
775 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
777 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
779 GSOCK_CONNECTION_FLAG
|
783 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
785 // Check pushback buffer before entering _Wait
789 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
790 // _Wait because of the semantics of WaitForRead: a return
791 // value of true means that a GSocket_Read call will return
792 // immediately, not that there is actually data to read.
794 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
799 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
801 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
804 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
806 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
809 // --------------------------------------------------------------------------
811 // --------------------------------------------------------------------------
814 // Get local or peer address
817 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
824 peer
= m_socket
->GetPeer();
826 // copying a null address would just trigger an assert anyway
831 addr_man
.SetAddress(peer
);
832 GAddress_destroy(peer
);
837 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
844 local
= m_socket
->GetLocal();
845 addr_man
.SetAddress(local
);
846 GAddress_destroy(local
);
852 // Save and restore socket state
855 void wxSocketBase::SaveState()
857 wxSocketState
*state
;
859 state
= new wxSocketState();
861 state
->m_flags
= m_flags
;
862 state
->m_notify
= m_notify
;
863 state
->m_eventmask
= m_eventmask
;
864 state
->m_clientData
= m_clientData
;
866 m_states
.Append(state
);
869 void wxSocketBase::RestoreState()
871 wxList::compatibility_iterator node
;
872 wxSocketState
*state
;
874 node
= m_states
.GetLast();
878 state
= (wxSocketState
*)node
->GetData();
880 m_flags
= state
->m_flags
;
881 m_notify
= state
->m_notify
;
882 m_eventmask
= state
->m_eventmask
;
883 m_clientData
= state
->m_clientData
;
885 m_states
.Erase(node
);
893 void wxSocketBase::SetTimeout(long seconds
)
898 m_socket
->SetTimeout(m_timeout
* 1000);
901 void wxSocketBase::SetFlags(wxSocketFlags flags
)
907 // --------------------------------------------------------------------------
909 // --------------------------------------------------------------------------
911 // A note on how events are processed, which is probably the most
912 // difficult thing to get working right while keeping the same API
913 // and functionality for all platforms.
915 // When GSocket detects an event, it calls wx_socket_callback, which in
916 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
917 // object. OnRequest does some housekeeping, and if the event is to be
918 // propagated to the user, it creates a new wxSocketEvent object and
919 // posts it. The event is not processed immediately, but delayed with
920 // AddPendingEvent instead. This is necessary in order to decouple the
921 // event processing from wx_socket_callback; otherwise, subsequent IO
922 // calls made from the user event handler would fail, as gtk callbacks
923 // are not reentrant.
925 // Note that, unlike events, user callbacks (now deprecated) are _not_
926 // decoupled from wx_socket_callback and thus they suffer from a variety
927 // of problems. Avoid them where possible and use events instead.
930 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
931 GSocketEvent notification
,
934 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
936 sckobj
->OnRequest((wxSocketNotify
) notification
);
939 void wxSocketBase::OnRequest(wxSocketNotify notification
)
941 // NOTE: We duplicate some of the code in _Wait, but this doesn't
942 // hurt. It has to be here because the (GSocket) event might arrive
943 // a bit delayed, and it has to be in _Wait as well because we don't
944 // know whether the Wait functions are being used.
948 case wxSOCKET_CONNECTION
:
949 m_establishing
= false;
953 // If we are in the middle of a R/W operation, do not
954 // propagate events to users. Also, filter 'late' events
955 // which are no longer valid.
958 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
962 case wxSOCKET_OUTPUT
:
963 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
969 m_establishing
= false;
976 // Schedule the event
978 wxSocketEventFlags flag
= 0;
980 switch (notification
)
982 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
983 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
984 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
985 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
987 wxLogWarning(_("wxSocket: unknown event!."));
991 if (((m_eventmask
& flag
) == flag
) && m_notify
)
995 wxSocketEvent
event(m_id
);
996 event
.m_event
= notification
;
997 event
.m_clientData
= m_clientData
;
998 event
.SetEventObject(this);
1000 m_handler
->AddPendingEvent(event
);
1005 void wxSocketBase::Notify(bool notify
)
1010 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1012 m_eventmask
= flags
;
1015 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1017 m_handler
= &handler
;
1021 // --------------------------------------------------------------------------
1023 // --------------------------------------------------------------------------
1025 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1029 if (m_unread
== NULL
)
1030 m_unread
= malloc(size
);
1035 tmp
= malloc(m_unrd_size
+ size
);
1036 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1042 m_unrd_size
+= size
;
1044 memcpy(m_unread
, buffer
, size
);
1047 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1052 if (size
> (m_unrd_size
-m_unrd_cur
))
1053 size
= m_unrd_size
-m_unrd_cur
;
1055 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1060 if (m_unrd_size
== m_unrd_cur
)
1073 // ==========================================================================
1075 // ==========================================================================
1077 // --------------------------------------------------------------------------
1079 // --------------------------------------------------------------------------
1081 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1082 wxSocketFlags flags
)
1083 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1085 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1087 m_socket
= GSocket_new();
1091 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1095 // Setup the socket as server
1097 m_socket
->SetLocal(addr_man
.GetAddress());
1099 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1100 m_socket
->SetReusable();
1103 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1108 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1112 m_socket
->SetTimeout(m_timeout
* 1000);
1113 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1114 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1115 wx_socket_callback
, (char *)this);
1118 // --------------------------------------------------------------------------
1120 // --------------------------------------------------------------------------
1122 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1124 GSocket
*child_socket
;
1129 // If wait == false, then the call should be nonblocking.
1130 // When we are finished, we put the socket to blocking mode
1134 m_socket
->SetNonBlocking(1);
1136 child_socket
= m_socket
->WaitConnection();
1139 m_socket
->SetNonBlocking(0);
1144 sock
.m_type
= wxSOCKET_BASE
;
1145 sock
.m_socket
= child_socket
;
1146 sock
.m_connected
= true;
1148 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1149 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1150 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1151 wx_socket_callback
, (char *)&sock
);
1156 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1158 wxSocketBase
* sock
= new wxSocketBase();
1160 sock
->SetFlags(m_flags
);
1162 if (!AcceptWith(*sock
, wait
))
1171 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1173 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1176 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1178 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1180 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1188 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1191 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1193 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1201 bool wxSocketBase::SetLocal(wxSockAddress
& local
)
1203 GAddress
* la
= local
.GetAddress();
1205 if (la
&& la
->m_addr
)
1207 m_socket
->SetLocal(la
);
1215 // ==========================================================================
1217 // ==========================================================================
1219 // --------------------------------------------------------------------------
1221 // --------------------------------------------------------------------------
1223 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1224 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1228 wxSocketClient::~wxSocketClient()
1232 // --------------------------------------------------------------------------
1234 // --------------------------------------------------------------------------
1236 bool wxSocketClient::DoConnect(wxSockAddress
& addr_man
, wxSockAddress
* local
, bool wait
)
1242 // Shutdown and destroy the socket
1247 m_socket
= GSocket_new();
1248 m_connected
= false;
1249 m_establishing
= false;
1254 m_socket
->SetTimeout(m_timeout
* 1000);
1255 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1256 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1257 wx_socket_callback
, (char *)this);
1259 // If wait == false, then the call should be nonblocking.
1260 // When we are finished, we put the socket to blocking mode
1264 m_socket
->SetNonBlocking(1);
1266 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1267 if (GetFlags() & wxSOCKET_REUSEADDR
)
1269 m_socket
->SetReusable();
1272 // Bind to the local IP address and port, when provided
1275 GAddress
* la
= local
->GetAddress();
1277 if (la
&& la
->m_addr
)
1278 m_socket
->SetLocal(la
);
1281 m_socket
->SetPeer(addr_man
.GetAddress());
1282 err
= m_socket
->Connect(GSOCK_STREAMED
);
1285 m_socket
->SetNonBlocking(0);
1287 if (err
!= GSOCK_NOERROR
)
1289 if (err
== GSOCK_WOULDBLOCK
)
1290 m_establishing
= true;
1299 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1301 return (DoConnect(addr_man
, NULL
, wait
));
1304 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, wxSockAddress
& local
, bool wait
)
1306 return (DoConnect(addr_man
, &local
, wait
));
1309 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1311 if (m_connected
) // Already connected
1314 if (!m_establishing
|| !m_socket
) // No connection in progress
1317 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1321 // ==========================================================================
1323 // ==========================================================================
1325 /* NOTE: experimental stuff - might change */
1327 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1328 wxSocketFlags flags
)
1329 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1331 // Create the socket
1332 m_socket
= GSocket_new();
1336 wxASSERT_MSG( 0, _T("datagram socket not new'd") );
1339 // Setup the socket as non connection oriented
1340 m_socket
->SetLocal(addr
.GetAddress());
1341 if( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1348 // Initialize all stuff
1349 m_connected
= false;
1350 m_establishing
= false;
1351 m_socket
->SetTimeout( m_timeout
);
1352 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1353 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1354 wx_socket_callback
, (char*)this );
1358 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1367 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1371 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1373 m_socket
->SetPeer(addr
.GetAddress());
1378 // ==========================================================================
1380 // ==========================================================================
1382 class wxSocketModule
: public wxModule
1385 virtual bool OnInit()
1387 // wxSocketBase will call GSocket_Init() itself when/if needed
1391 virtual void OnExit()
1393 if ( wxSocketBase::IsInitialized() )
1394 wxSocketBase::Shutdown();
1398 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1401 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)