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"
26 #include "wx/apptrait.h"
27 #include "wx/object.h"
28 #include "wx/string.h"
31 #include "wx/module.h"
36 #include "wx/sckaddr.h"
37 #include "wx/socket.h"
38 #include "wx/datetime.h"
40 // DLL options compatibility check:
42 WX_CHECK_BUILD_OPTIONS("wxNet")
44 // --------------------------------------------------------------------------
45 // macros and constants
46 // --------------------------------------------------------------------------
49 #define MAX_DISCARD_SIZE (10 * 1024)
51 // what to do within waits: we have 2 cases: from the main thread itself we
52 // have to call wxYield() to let the events (including the GUI events and the
53 // low-level (not wxWidgets) events from GSocket) be processed. From another
54 // thread it is enough to just call wxThread::Yield() which will give away the
55 // rest of our time slice: the explanation is that the events will be processed
56 // by the main thread anyhow, without calling wxYield(), but we don't want to
57 // eat the CPU time uselessly while sitting in the loop waiting for the data
59 #define PROCESS_EVENTS() \
61 if ( wxThread::IsMain() ) \
66 #else // !wxUSE_THREADS
67 #define PROCESS_EVENTS() wxYield()
68 #endif // wxUSE_THREADS/!wxUSE_THREADS
70 #define wxTRACE_Socket _T("wxSocket")
72 // --------------------------------------------------------------------------
74 // --------------------------------------------------------------------------
76 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
77 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
78 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
79 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
80 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
82 // --------------------------------------------------------------------------
84 // --------------------------------------------------------------------------
86 class wxSocketState
: public wxObject
89 wxSocketFlags m_flags
;
90 wxSocketEventFlags m_eventmask
;
95 wxSocketState() : wxObject() {}
97 DECLARE_NO_COPY_CLASS(wxSocketState
)
100 // ==========================================================================
102 // ==========================================================================
104 // --------------------------------------------------------------------------
105 // Initialization and shutdown
106 // --------------------------------------------------------------------------
108 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
109 // to m_countInit with a crit section
110 size_t wxSocketBase::m_countInit
= 0;
112 bool wxSocketBase::IsInitialized()
114 return m_countInit
> 0;
117 bool wxSocketBase::Initialize()
119 if ( !m_countInit
++ )
122 Details: Initialize() creates a hidden window as a sink for socket
123 events, such as 'read completed'. wxMSW has only one message loop
124 for the main thread. If Initialize is called in a secondary thread,
125 the socket window will be created for the secondary thread, but
126 since there is no message loop on this thread, it will never
127 receive events and all socket operations will time out.
128 BTW, the main thread must not be stopped using sleep or block
129 on a semaphore (a bad idea in any case) or socket operations
132 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
133 the main thread. Because secondary threads do not have run loops,
134 adding event notifications to the "Current" loop would have no
135 effect at all, events would never fire.
137 wxASSERT_MSG( wxIsMainThread(),
138 wxT("Call wxSocketBase::Initialize() from the main thread first!"));
140 wxAppTraits
*traits
= wxAppConsole::GetInstance() ?
141 wxAppConsole::GetInstance()->GetTraits() : NULL
;
142 GSocketGUIFunctionsTable
*functions
=
143 traits
? traits
->GetSocketGUIFunctionsTable() : NULL
;
144 GSocket_SetGUIFunctions(functions
);
146 if ( !GSocket_Init() )
157 void wxSocketBase::Shutdown()
159 // we should be initialized
160 wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") );
161 if ( --m_countInit
== 0 )
167 // --------------------------------------------------------------------------
169 // --------------------------------------------------------------------------
171 void wxSocketBase::Init()
174 m_type
= wxSOCKET_UNINIT
;
185 m_beingDeleted
= false;
199 if ( !IsInitialized() )
201 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
202 // other calls to it should be matched by a call to Shutdown()
207 wxSocketBase::wxSocketBase()
212 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
220 wxSocketBase::~wxSocketBase()
222 // Just in case the app called Destroy() *and* then deleted
223 // the socket immediately: don't leave dangling pointers.
224 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
226 traits
->RemoveFromPendingDelete(this);
228 // Shutdown and close the socket
232 // Destroy the GSocket object
236 // Free the pushback buffer
241 bool wxSocketBase::Destroy()
243 // Delayed destruction: the socket will be deleted during the next
244 // idle loop iteration. This ensures that all pending events have
246 m_beingDeleted
= true;
248 // Shutdown and close the socket
251 // Supress events from now on
254 // schedule this object for deletion
255 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
258 // let the traits object decide what to do with us
259 traits
->ScheduleForDestroy(this);
261 else // no app or no traits
263 // in wxBase we might have no app object at all, don't leak memory
270 // --------------------------------------------------------------------------
272 // --------------------------------------------------------------------------
274 // The following IO operations update m_error and m_lcount:
275 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
277 // TODO: Should Connect, Accept and AcceptWith update m_error?
279 bool wxSocketBase::Close()
281 // Interrupt pending waits
287 m_socket
->UnsetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
288 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
290 // Shutdown the connection
291 m_socket
->Shutdown();
295 m_establishing
= false;
299 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
304 m_lcount
= _Read(buffer
, nbytes
);
306 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
307 if (m_flags
& wxSOCKET_WAITALL
)
308 m_error
= (m_lcount
!= nbytes
);
310 m_error
= (m_lcount
== 0);
312 // Allow read events from now on
318 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
322 // Try the pushback buffer first
323 total
= GetPushback(buffer
, nbytes
, false);
325 buffer
= (char *)buffer
+ total
;
327 // Return now in one of the following cases:
328 // - the socket is invalid,
329 // - we got all the data,
330 // - we got *some* data and we are not using wxSOCKET_WAITALL.
333 ((total
!= 0) && !(m_flags
& wxSOCKET_WAITALL
)) )
336 // Possible combinations (they are checked in this order)
338 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
343 if (m_flags
& wxSOCKET_NOWAIT
)
345 m_socket
->SetNonBlocking(1);
346 ret
= m_socket
->Read((char *)buffer
, nbytes
);
347 m_socket
->SetNonBlocking(0);
358 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
361 ret
= m_socket
->Read((char *)buffer
, nbytes
);
367 buffer
= (char *)buffer
+ ret
;
370 // If we got here and wxSOCKET_WAITALL is not set, we can leave
371 // now. Otherwise, wait until we recv all the data or until there
374 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
381 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
383 wxUint32 len
, len2
, sig
, total
;
388 unsigned char sig
[4];
389 unsigned char len
[4];
398 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
400 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
403 sig
= (wxUint32
)msg
.sig
[0];
404 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
405 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
406 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
408 if (sig
!= 0xfeeddead)
410 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
414 len
= (wxUint32
)msg
.len
[0];
415 len
|= (wxUint32
)(msg
.len
[1] << 8);
416 len
|= (wxUint32
)(msg
.len
[2] << 16);
417 len
|= (wxUint32
)(msg
.len
[3] << 24);
427 // Don't attemp to read if the msg was zero bytes long.
430 total
= _Read(buffer
, len
);
437 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
440 // NOTE: discarded bytes don't add to m_lcount.
443 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
444 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
445 len2
-= (wxUint32
)discard_len
;
447 while ((discard_len
> 0) && len2
);
449 delete [] discard_buffer
;
454 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
457 sig
= (wxUint32
)msg
.sig
[0];
458 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
459 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
460 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
462 if (sig
!= 0xdeadfeed)
464 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
480 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
485 m_lcount
= _Read(buffer
, nbytes
);
486 Pushback(buffer
, m_lcount
);
488 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
489 if (m_flags
& wxSOCKET_WAITALL
)
490 m_error
= (m_lcount
!= nbytes
);
492 m_error
= (m_lcount
== 0);
494 // Allow read events again
500 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
505 m_lcount
= _Write(buffer
, nbytes
);
507 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
508 if (m_flags
& wxSOCKET_WAITALL
)
509 m_error
= (m_lcount
!= nbytes
);
511 m_error
= (m_lcount
== 0);
513 // Allow write events again
519 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
523 // If the socket is invalid or parameters are ill, return immediately
524 if (!m_socket
|| !buffer
|| !nbytes
)
527 // Possible combinations (they are checked in this order)
529 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
534 if (m_flags
& wxSOCKET_NOWAIT
)
536 m_socket
->SetNonBlocking(1);
537 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
538 m_socket
->SetNonBlocking(0);
549 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
552 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
558 buffer
= (const char *)buffer
+ ret
;
561 // If we got here and wxSOCKET_WAITALL is not set, we can leave
562 // now. Otherwise, wait until we send all the data or until there
565 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
572 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
578 unsigned char sig
[4];
579 unsigned char len
[4];
587 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
589 msg
.sig
[0] = (unsigned char) 0xad;
590 msg
.sig
[1] = (unsigned char) 0xde;
591 msg
.sig
[2] = (unsigned char) 0xed;
592 msg
.sig
[3] = (unsigned char) 0xfe;
594 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
595 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
596 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
597 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
599 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
602 total
= _Write(buffer
, nbytes
);
607 msg
.sig
[0] = (unsigned char) 0xed;
608 msg
.sig
[1] = (unsigned char) 0xfe;
609 msg
.sig
[2] = (unsigned char) 0xad;
610 msg
.sig
[3] = (unsigned char) 0xde;
611 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
613 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
627 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
630 Pushback(buffer
, nbytes
);
638 wxSocketBase
& wxSocketBase::Discard()
640 char *buffer
= new char[MAX_DISCARD_SIZE
];
647 SetFlags(wxSOCKET_NOWAIT
);
651 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
654 while (ret
== MAX_DISCARD_SIZE
);
660 // Allow read events again
666 // --------------------------------------------------------------------------
668 // --------------------------------------------------------------------------
670 // All Wait functions poll the socket using GSocket_Select() to
671 // check for the specified combination of conditions, until one
672 // of these conditions become true, an error occurs, or the
673 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
674 // this won't block the GUI.
676 bool wxSocketBase::_Wait(long seconds
,
678 wxSocketEventFlags flags
)
680 GSocketEventFlags result
;
683 // Set this to true to interrupt ongoing waits
686 // Check for valid socket
690 // Check for valid timeout value.
692 timeout
= seconds
* 1000 + milliseconds
;
694 timeout
= m_timeout
* 1000;
696 bool has_event_loop
= wxTheApp
->GetTraits() ? (wxTheApp
->GetTraits()->GetSocketGUIFunctionsTable() ? true : false) : false;
698 // Wait in an active polling loop.
700 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
701 // hurt. It has to be here because the (GSocket) event might arrive
702 // a bit delayed, and it has to be in OnRequest as well because we
703 // don't know whether the Wait functions are being used.
705 // Do this at least once (important if timeout == 0, when
706 // we are just polling). Also, if just polling, do not yield.
708 wxDateTime current_time
= wxDateTime::UNow();
709 unsigned int time_limit
= (current_time
.GetTicks() * 1000) + current_time
.GetMillisecond() + timeout
;
711 bool valid_result
= false;
715 // This is used to avoid a busy loop on wxBase - having a select
716 // timeout of 50 ms per iteration should be enough.
718 m_socket
->SetTimeout(50);
720 m_socket
->SetTimeout(timeout
);
725 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
727 // Incoming connection (server) or connection established (client)
728 if (result
& GSOCK_CONNECTION_FLAG
)
731 m_establishing
= false;
736 // Data available or output buffer ready
737 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
744 if (result
& GSOCK_LOST_FLAG
)
747 m_establishing
= false;
748 valid_result
= ((flags
& GSOCK_LOST_FLAG
) != 0);
753 current_time
= wxDateTime::UNow();
754 int time_left
= time_limit
- ((current_time
.GetTicks() * 1000) + current_time
.GetMillisecond());
755 if ((!timeout
) || (time_left
<= 0) || (m_interrupt
))
765 // If there's less than 50 ms left, just call select with that timeout.
767 m_socket
->SetTimeout(time_left
);
772 // Set timeout back to original value (we overwrote it for polling)
774 m_socket
->SetTimeout(m_timeout
*1000);
779 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
781 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
783 GSOCK_CONNECTION_FLAG
|
787 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
789 // Check pushback buffer before entering _Wait
793 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
794 // _Wait because of the semantics of WaitForRead: a return
795 // value of true means that a GSocket_Read call will return
796 // immediately, not that there is actually data to read.
798 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
803 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
805 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
808 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
810 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
813 // --------------------------------------------------------------------------
815 // --------------------------------------------------------------------------
818 // Get local or peer address
821 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
828 peer
= m_socket
->GetPeer();
830 // copying a null address would just trigger an assert anyway
835 addr_man
.SetAddress(peer
);
836 GAddress_destroy(peer
);
841 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
848 local
= m_socket
->GetLocal();
849 addr_man
.SetAddress(local
);
850 GAddress_destroy(local
);
856 // Save and restore socket state
859 void wxSocketBase::SaveState()
861 wxSocketState
*state
;
863 state
= new wxSocketState();
865 state
->m_flags
= m_flags
;
866 state
->m_notify
= m_notify
;
867 state
->m_eventmask
= m_eventmask
;
868 state
->m_clientData
= m_clientData
;
870 m_states
.Append(state
);
873 void wxSocketBase::RestoreState()
875 wxList::compatibility_iterator node
;
876 wxSocketState
*state
;
878 node
= m_states
.GetLast();
882 state
= (wxSocketState
*)node
->GetData();
884 m_flags
= state
->m_flags
;
885 m_notify
= state
->m_notify
;
886 m_eventmask
= state
->m_eventmask
;
887 m_clientData
= state
->m_clientData
;
889 m_states
.Erase(node
);
897 void wxSocketBase::SetTimeout(long seconds
)
902 m_socket
->SetTimeout(m_timeout
* 1000);
905 void wxSocketBase::SetFlags(wxSocketFlags flags
)
911 // --------------------------------------------------------------------------
913 // --------------------------------------------------------------------------
915 // A note on how events are processed, which is probably the most
916 // difficult thing to get working right while keeping the same API
917 // and functionality for all platforms.
919 // When GSocket detects an event, it calls wx_socket_callback, which in
920 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
921 // object. OnRequest does some housekeeping, and if the event is to be
922 // propagated to the user, it creates a new wxSocketEvent object and
923 // posts it. The event is not processed immediately, but delayed with
924 // AddPendingEvent instead. This is necessary in order to decouple the
925 // event processing from wx_socket_callback; otherwise, subsequent IO
926 // calls made from the user event handler would fail, as gtk callbacks
927 // are not reentrant.
929 // Note that, unlike events, user callbacks (now deprecated) are _not_
930 // decoupled from wx_socket_callback and thus they suffer from a variety
931 // of problems. Avoid them where possible and use events instead.
934 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
935 GSocketEvent notification
,
938 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
940 sckobj
->OnRequest((wxSocketNotify
) notification
);
943 void wxSocketBase::OnRequest(wxSocketNotify notification
)
945 // NOTE: We duplicate some of the code in _Wait, but this doesn't
946 // hurt. It has to be here because the (GSocket) event might arrive
947 // a bit delayed, and it has to be in _Wait as well because we don't
948 // know whether the Wait functions are being used.
952 case wxSOCKET_CONNECTION
:
953 m_establishing
= false;
957 // If we are in the middle of a R/W operation, do not
958 // propagate events to users. Also, filter 'late' events
959 // which are no longer valid.
962 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
966 case wxSOCKET_OUTPUT
:
967 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
973 m_establishing
= false;
980 // Schedule the event
982 wxSocketEventFlags flag
= 0;
984 switch (notification
)
986 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
987 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
988 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
989 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
991 wxLogWarning(_("wxSocket: unknown event!."));
995 if (((m_eventmask
& flag
) == flag
) && m_notify
)
999 wxSocketEvent
event(m_id
);
1000 event
.m_event
= notification
;
1001 event
.m_clientData
= m_clientData
;
1002 event
.SetEventObject(this);
1004 m_handler
->AddPendingEvent(event
);
1009 void wxSocketBase::Notify(bool notify
)
1014 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1016 m_eventmask
= flags
;
1019 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1021 m_handler
= &handler
;
1025 // --------------------------------------------------------------------------
1027 // --------------------------------------------------------------------------
1029 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1033 if (m_unread
== NULL
)
1034 m_unread
= malloc(size
);
1039 tmp
= malloc(m_unrd_size
+ size
);
1040 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1046 m_unrd_size
+= size
;
1048 memcpy(m_unread
, buffer
, size
);
1051 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1056 if (size
> (m_unrd_size
-m_unrd_cur
))
1057 size
= m_unrd_size
-m_unrd_cur
;
1059 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1064 if (m_unrd_size
== m_unrd_cur
)
1077 // ==========================================================================
1079 // ==========================================================================
1081 // --------------------------------------------------------------------------
1083 // --------------------------------------------------------------------------
1085 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1086 wxSocketFlags flags
)
1087 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1089 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1091 m_socket
= GSocket_new();
1095 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1099 // Setup the socket as server
1101 m_socket
->SetLocal(addr_man
.GetAddress());
1103 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1104 m_socket
->SetReusable();
1107 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1112 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1116 m_socket
->SetTimeout(m_timeout
* 1000);
1117 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1118 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1119 wx_socket_callback
, (char *)this);
1122 // --------------------------------------------------------------------------
1124 // --------------------------------------------------------------------------
1126 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1128 GSocket
*child_socket
;
1133 // If wait == false, then the call should be nonblocking.
1134 // When we are finished, we put the socket to blocking mode
1138 m_socket
->SetNonBlocking(1);
1140 child_socket
= m_socket
->WaitConnection();
1143 m_socket
->SetNonBlocking(0);
1148 sock
.m_type
= wxSOCKET_BASE
;
1149 sock
.m_socket
= child_socket
;
1150 sock
.m_connected
= true;
1152 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1153 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1154 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1155 wx_socket_callback
, (char *)&sock
);
1160 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1162 wxSocketBase
* sock
= new wxSocketBase();
1164 sock
->SetFlags(m_flags
);
1166 if (!AcceptWith(*sock
, wait
))
1175 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1177 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1180 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1182 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1184 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1192 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1195 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1197 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1205 bool wxSocketBase::SetLocal(wxIPV4address
& local
)
1207 GAddress
* la
= local
.GetAddress();
1209 // If the address is valid, save it for use when we call Connect
1210 if (la
&& la
->m_addr
)
1212 m_localAddress
= local
;
1220 // ==========================================================================
1222 // ==========================================================================
1224 // --------------------------------------------------------------------------
1226 // --------------------------------------------------------------------------
1228 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1229 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1233 wxSocketClient::~wxSocketClient()
1237 // --------------------------------------------------------------------------
1239 // --------------------------------------------------------------------------
1241 bool wxSocketClient::DoConnect(wxSockAddress
& addr_man
, wxSockAddress
* local
, bool wait
)
1247 // Shutdown and destroy the socket
1252 m_socket
= GSocket_new();
1253 m_connected
= false;
1254 m_establishing
= false;
1259 m_socket
->SetTimeout(m_timeout
* 1000);
1260 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1261 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1262 wx_socket_callback
, (char *)this);
1264 // If wait == false, then the call should be nonblocking.
1265 // When we are finished, we put the socket to blocking mode
1269 m_socket
->SetNonBlocking(1);
1271 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1272 if (GetFlags() & wxSOCKET_REUSEADDR
)
1274 m_socket
->SetReusable();
1277 // If no local address was passed and one has been set, use the one that was Set
1278 if (!local
&& m_localAddress
.GetAddress())
1280 local
= &m_localAddress
;
1283 // Bind to the local IP address and port, when provided
1286 GAddress
* la
= local
->GetAddress();
1288 if (la
&& la
->m_addr
)
1289 m_socket
->SetLocal(la
);
1292 m_socket
->SetPeer(addr_man
.GetAddress());
1293 err
= m_socket
->Connect(GSOCK_STREAMED
);
1296 m_socket
->SetNonBlocking(0);
1298 if (err
!= GSOCK_NOERROR
)
1300 if (err
== GSOCK_WOULDBLOCK
)
1301 m_establishing
= true;
1310 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1312 return (DoConnect(addr_man
, NULL
, wait
));
1315 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, wxSockAddress
& local
, bool wait
)
1317 return (DoConnect(addr_man
, &local
, wait
));
1320 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1322 if (m_connected
) // Already connected
1325 if (!m_establishing
|| !m_socket
) // No connection in progress
1328 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1332 // ==========================================================================
1334 // ==========================================================================
1336 /* NOTE: experimental stuff - might change */
1338 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1339 wxSocketFlags flags
)
1340 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1342 // Create the socket
1343 m_socket
= GSocket_new();
1347 wxFAIL_MSG( _T("datagram socket not new'd") );
1350 // Setup the socket as non connection oriented
1351 m_socket
->SetLocal(addr
.GetAddress());
1352 if( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1359 // Initialize all stuff
1360 m_connected
= false;
1361 m_establishing
= false;
1362 m_socket
->SetTimeout( m_timeout
);
1363 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1364 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1365 wx_socket_callback
, (char*)this );
1368 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1377 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1381 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1383 m_socket
->SetPeer(addr
.GetAddress());
1388 // ==========================================================================
1390 // ==========================================================================
1392 class wxSocketModule
: public wxModule
1395 virtual bool OnInit()
1397 // wxSocketBase will call GSocket_Init() itself when/if needed
1401 virtual void OnExit()
1403 if ( wxSocketBase::IsInitialized() )
1404 wxSocketBase::Shutdown();
1408 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1411 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)