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
)