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/object.h"
30 #include "wx/apptrait.h"
31 #include "wx/string.h"
34 #include "wx/module.h"
39 #include "wx/sckaddr.h"
40 #include "wx/socket.h"
41 #include "wx/datetime.h"
43 // DLL options compatibility check:
45 WX_CHECK_BUILD_OPTIONS("wxNet")
47 // --------------------------------------------------------------------------
48 // macros and constants
49 // --------------------------------------------------------------------------
52 #define MAX_DISCARD_SIZE (10 * 1024)
54 // what to do within waits: we have 2 cases: from the main thread itself we
55 // have to call wxYield() to let the events (including the GUI events and the
56 // low-level (not wxWidgets) events from GSocket) be processed. From another
57 // thread it is enough to just call wxThread::Yield() which will give away the
58 // rest of our time slice: the explanation is that the events will be processed
59 // by the main thread anyhow, without calling wxYield(), but we don't want to
60 // eat the CPU time uselessly while sitting in the loop waiting for the data
62 #define PROCESS_EVENTS() \
64 if ( wxThread::IsMain() ) \
69 #else // !wxUSE_THREADS
70 #define PROCESS_EVENTS() wxYield()
71 #endif // wxUSE_THREADS/!wxUSE_THREADS
73 #define wxTRACE_Socket _T("wxSocket")
75 // --------------------------------------------------------------------------
77 // --------------------------------------------------------------------------
79 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
80 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
81 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
82 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
83 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
85 // --------------------------------------------------------------------------
87 // --------------------------------------------------------------------------
89 class wxSocketState
: public wxObject
92 wxSocketFlags m_flags
;
93 wxSocketEventFlags m_eventmask
;
98 wxSocketState() : wxObject() {}
100 DECLARE_NO_COPY_CLASS(wxSocketState
)
103 // ==========================================================================
105 // ==========================================================================
107 // --------------------------------------------------------------------------
108 // Initialization and shutdown
109 // --------------------------------------------------------------------------
111 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
112 // to m_countInit with a crit section
113 size_t wxSocketBase::m_countInit
= 0;
115 bool wxSocketBase::IsInitialized()
117 return m_countInit
> 0;
120 bool wxSocketBase::Initialize()
122 if ( !m_countInit
++ )
125 Details: Initialize() creates a hidden window as a sink for socket
126 events, such as 'read completed'. wxMSW has only one message loop
127 for the main thread. If Initialize is called in a secondary thread,
128 the socket window will be created for the secondary thread, but
129 since there is no message loop on this thread, it will never
130 receive events and all socket operations will time out.
131 BTW, the main thread must not be stopped using sleep or block
132 on a semaphore (a bad idea in any case) or socket operations
135 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
136 the main thread. Because secondary threads do not have run loops,
137 adding event notifications to the "Current" loop would have no
138 effect at all, events would never fire.
140 wxASSERT_MSG( wxIsMainThread(),
141 wxT("Call wxSocketBase::Initialize() from the main thread first!"));
143 wxAppTraits
*traits
= wxAppConsole::GetInstance() ?
144 wxAppConsole::GetInstance()->GetTraits() : NULL
;
145 GSocketGUIFunctionsTable
*functions
=
146 traits
? traits
->GetSocketGUIFunctionsTable() : NULL
;
147 GSocket_SetGUIFunctions(functions
);
149 if ( !GSocket_Init() )
160 void wxSocketBase::Shutdown()
162 // we should be initialized
163 wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") );
164 if ( --m_countInit
== 0 )
170 // --------------------------------------------------------------------------
172 // --------------------------------------------------------------------------
174 void wxSocketBase::Init()
177 m_type
= wxSOCKET_UNINIT
;
188 m_beingDeleted
= false;
202 if ( !IsInitialized() )
204 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
205 // other calls to it should be matched by a call to Shutdown()
210 wxSocketBase::wxSocketBase()
215 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
223 wxSocketBase::~wxSocketBase()
225 // Just in case the app called Destroy() *and* then deleted
226 // the socket immediately: don't leave dangling pointers.
227 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
229 traits
->RemoveFromPendingDelete(this);
231 // Shutdown and close the socket
235 // Destroy the GSocket object
239 // Free the pushback buffer
244 bool wxSocketBase::Destroy()
246 // Delayed destruction: the socket will be deleted during the next
247 // idle loop iteration. This ensures that all pending events have
249 m_beingDeleted
= true;
251 // Shutdown and close the socket
254 // Supress events from now on
257 // schedule this object for deletion
258 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
261 // let the traits object decide what to do with us
262 traits
->ScheduleForDestroy(this);
264 else // no app or no traits
266 // in wxBase we might have no app object at all, don't leak memory
273 // --------------------------------------------------------------------------
275 // --------------------------------------------------------------------------
277 // The following IO operations update m_error and m_lcount:
278 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
280 // TODO: Should Connect, Accept and AcceptWith update m_error?
282 bool wxSocketBase::Close()
284 // Interrupt pending waits
290 m_socket
->UnsetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
291 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
293 // Shutdown the connection
294 m_socket
->Shutdown();
298 m_establishing
= false;
302 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
307 m_lcount
= _Read(buffer
, nbytes
);
309 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
310 if (m_flags
& wxSOCKET_WAITALL
)
311 m_error
= (m_lcount
!= nbytes
);
313 m_error
= (m_lcount
== 0);
315 // Allow read events from now on
321 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
325 // Try the pushback buffer first
326 total
= GetPushback(buffer
, nbytes
, false);
328 buffer
= (char *)buffer
+ total
;
330 // Return now in one of the following cases:
331 // - the socket is invalid,
332 // - we got all the data,
333 // - we got *some* data and we are not using wxSOCKET_WAITALL.
336 ((total
!= 0) && !(m_flags
& wxSOCKET_WAITALL
)) )
339 // Possible combinations (they are checked in this order)
341 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
346 if (m_flags
& wxSOCKET_NOWAIT
)
348 m_socket
->SetNonBlocking(1);
349 ret
= m_socket
->Read((char *)buffer
, nbytes
);
350 m_socket
->SetNonBlocking(0);
361 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
364 ret
= m_socket
->Read((char *)buffer
, nbytes
);
370 buffer
= (char *)buffer
+ ret
;
373 // If we got here and wxSOCKET_WAITALL is not set, we can leave
374 // now. Otherwise, wait until we recv all the data or until there
377 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
384 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
386 wxUint32 len
, len2
, sig
, total
;
391 unsigned char sig
[4];
392 unsigned char len
[4];
401 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
403 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
406 sig
= (wxUint32
)msg
.sig
[0];
407 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
408 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
409 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
411 if (sig
!= 0xfeeddead)
413 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
417 len
= (wxUint32
)msg
.len
[0];
418 len
|= (wxUint32
)(msg
.len
[1] << 8);
419 len
|= (wxUint32
)(msg
.len
[2] << 16);
420 len
|= (wxUint32
)(msg
.len
[3] << 24);
430 // Don't attemp to read if the msg was zero bytes long.
433 total
= _Read(buffer
, len
);
440 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
443 // NOTE: discarded bytes don't add to m_lcount.
446 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
447 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
448 len2
-= (wxUint32
)discard_len
;
450 while ((discard_len
> 0) && len2
);
452 delete [] discard_buffer
;
457 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
460 sig
= (wxUint32
)msg
.sig
[0];
461 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
462 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
463 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
465 if (sig
!= 0xdeadfeed)
467 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
483 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
488 m_lcount
= _Read(buffer
, nbytes
);
489 Pushback(buffer
, m_lcount
);
491 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
492 if (m_flags
& wxSOCKET_WAITALL
)
493 m_error
= (m_lcount
!= nbytes
);
495 m_error
= (m_lcount
== 0);
497 // Allow read events again
503 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
508 m_lcount
= _Write(buffer
, nbytes
);
510 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
511 if (m_flags
& wxSOCKET_WAITALL
)
512 m_error
= (m_lcount
!= nbytes
);
514 m_error
= (m_lcount
== 0);
516 // Allow write events again
522 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
526 // If the socket is invalid or parameters are ill, return immediately
527 if (!m_socket
|| !buffer
|| !nbytes
)
530 // Possible combinations (they are checked in this order)
532 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
537 if (m_flags
& wxSOCKET_NOWAIT
)
539 m_socket
->SetNonBlocking(1);
540 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
541 m_socket
->SetNonBlocking(0);
552 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
555 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
561 buffer
= (const char *)buffer
+ ret
;
564 // If we got here and wxSOCKET_WAITALL is not set, we can leave
565 // now. Otherwise, wait until we send all the data or until there
568 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
575 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
581 unsigned char sig
[4];
582 unsigned char len
[4];
590 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
592 msg
.sig
[0] = (unsigned char) 0xad;
593 msg
.sig
[1] = (unsigned char) 0xde;
594 msg
.sig
[2] = (unsigned char) 0xed;
595 msg
.sig
[3] = (unsigned char) 0xfe;
597 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
598 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
599 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
600 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
602 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
605 total
= _Write(buffer
, nbytes
);
610 msg
.sig
[0] = (unsigned char) 0xed;
611 msg
.sig
[1] = (unsigned char) 0xfe;
612 msg
.sig
[2] = (unsigned char) 0xad;
613 msg
.sig
[3] = (unsigned char) 0xde;
614 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
616 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
630 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
633 Pushback(buffer
, nbytes
);
641 wxSocketBase
& wxSocketBase::Discard()
643 char *buffer
= new char[MAX_DISCARD_SIZE
];
650 SetFlags(wxSOCKET_NOWAIT
);
654 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
657 while (ret
== MAX_DISCARD_SIZE
);
663 // Allow read events again
669 // --------------------------------------------------------------------------
671 // --------------------------------------------------------------------------
673 // All Wait functions poll the socket using GSocket_Select() to
674 // check for the specified combination of conditions, until one
675 // of these conditions become true, an error occurs, or the
676 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
677 // this won't block the GUI.
679 bool wxSocketBase::_Wait(long seconds
,
681 wxSocketEventFlags flags
)
683 GSocketEventFlags result
;
686 // Set this to true to interrupt ongoing waits
689 // Check for valid socket
693 // Check for valid timeout value.
695 timeout
= seconds
* 1000 + milliseconds
;
697 timeout
= m_timeout
* 1000;
699 bool has_event_loop
= wxTheApp
->GetTraits() ? (wxTheApp
->GetTraits()->GetSocketGUIFunctionsTable() ? true : false) : false;
701 // Wait in an active polling loop.
703 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
704 // hurt. It has to be here because the (GSocket) event might arrive
705 // a bit delayed, and it has to be in OnRequest as well because we
706 // don't know whether the Wait functions are being used.
708 // Do this at least once (important if timeout == 0, when
709 // we are just polling). Also, if just polling, do not yield.
711 wxDateTime current_time
= wxDateTime::UNow();
712 unsigned int time_limit
= (current_time
.GetTicks() * 1000) + current_time
.GetMillisecond() + timeout
;
714 bool valid_result
= false;
718 // This is used to avoid a busy loop on wxBase - having a select
719 // timeout of 50 ms per iteration should be enough.
721 m_socket
->SetTimeout(50);
723 m_socket
->SetTimeout(timeout
);
728 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
730 // Incoming connection (server) or connection established (client)
731 if (result
& GSOCK_CONNECTION_FLAG
)
734 m_establishing
= false;
739 // Data available or output buffer ready
740 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
747 if (result
& GSOCK_LOST_FLAG
)
750 m_establishing
= false;
751 valid_result
= ((flags
& GSOCK_LOST_FLAG
) != 0);
756 current_time
= wxDateTime::UNow();
757 int time_left
= time_limit
- ((current_time
.GetTicks() * 1000) + current_time
.GetMillisecond());
758 if ((!timeout
) || (time_left
<= 0) || (m_interrupt
))
768 // If there's less than 50 ms left, just call select with that timeout.
770 m_socket
->SetTimeout(time_left
);
775 // Set timeout back to original value (we overwrote it for polling)
777 m_socket
->SetTimeout(m_timeout
*1000);
782 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
784 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
786 GSOCK_CONNECTION_FLAG
|
790 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
792 // Check pushback buffer before entering _Wait
796 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
797 // _Wait because of the semantics of WaitForRead: a return
798 // value of true means that a GSocket_Read call will return
799 // immediately, not that there is actually data to read.
801 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
806 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
808 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
811 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
813 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
816 // --------------------------------------------------------------------------
818 // --------------------------------------------------------------------------
821 // Get local or peer address
824 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
831 peer
= m_socket
->GetPeer();
833 // copying a null address would just trigger an assert anyway
838 addr_man
.SetAddress(peer
);
839 GAddress_destroy(peer
);
844 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
851 local
= m_socket
->GetLocal();
852 addr_man
.SetAddress(local
);
853 GAddress_destroy(local
);
859 // Save and restore socket state
862 void wxSocketBase::SaveState()
864 wxSocketState
*state
;
866 state
= new wxSocketState();
868 state
->m_flags
= m_flags
;
869 state
->m_notify
= m_notify
;
870 state
->m_eventmask
= m_eventmask
;
871 state
->m_clientData
= m_clientData
;
873 m_states
.Append(state
);
876 void wxSocketBase::RestoreState()
878 wxList::compatibility_iterator node
;
879 wxSocketState
*state
;
881 node
= m_states
.GetLast();
885 state
= (wxSocketState
*)node
->GetData();
887 m_flags
= state
->m_flags
;
888 m_notify
= state
->m_notify
;
889 m_eventmask
= state
->m_eventmask
;
890 m_clientData
= state
->m_clientData
;
892 m_states
.Erase(node
);
900 void wxSocketBase::SetTimeout(long seconds
)
905 m_socket
->SetTimeout(m_timeout
* 1000);
908 void wxSocketBase::SetFlags(wxSocketFlags flags
)
914 // --------------------------------------------------------------------------
916 // --------------------------------------------------------------------------
918 // A note on how events are processed, which is probably the most
919 // difficult thing to get working right while keeping the same API
920 // and functionality for all platforms.
922 // When GSocket detects an event, it calls wx_socket_callback, which in
923 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
924 // object. OnRequest does some housekeeping, and if the event is to be
925 // propagated to the user, it creates a new wxSocketEvent object and
926 // posts it. The event is not processed immediately, but delayed with
927 // AddPendingEvent instead. This is necessary in order to decouple the
928 // event processing from wx_socket_callback; otherwise, subsequent IO
929 // calls made from the user event handler would fail, as gtk callbacks
930 // are not reentrant.
932 // Note that, unlike events, user callbacks (now deprecated) are _not_
933 // decoupled from wx_socket_callback and thus they suffer from a variety
934 // of problems. Avoid them where possible and use events instead.
937 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
938 GSocketEvent notification
,
941 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
943 sckobj
->OnRequest((wxSocketNotify
) notification
);
946 void wxSocketBase::OnRequest(wxSocketNotify notification
)
948 // NOTE: We duplicate some of the code in _Wait, but this doesn't
949 // hurt. It has to be here because the (GSocket) event might arrive
950 // a bit delayed, and it has to be in _Wait as well because we don't
951 // know whether the Wait functions are being used.
955 case wxSOCKET_CONNECTION
:
956 m_establishing
= false;
960 // If we are in the middle of a R/W operation, do not
961 // propagate events to users. Also, filter 'late' events
962 // which are no longer valid.
965 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
969 case wxSOCKET_OUTPUT
:
970 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
976 m_establishing
= false;
983 // Schedule the event
985 wxSocketEventFlags flag
= 0;
987 switch (notification
)
989 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
990 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
991 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
992 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
994 wxLogWarning(_("wxSocket: unknown event!."));
998 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1002 wxSocketEvent
event(m_id
);
1003 event
.m_event
= notification
;
1004 event
.m_clientData
= m_clientData
;
1005 event
.SetEventObject(this);
1007 m_handler
->AddPendingEvent(event
);
1012 void wxSocketBase::Notify(bool notify
)
1017 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1019 m_eventmask
= flags
;
1022 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1024 m_handler
= &handler
;
1028 // --------------------------------------------------------------------------
1030 // --------------------------------------------------------------------------
1032 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1036 if (m_unread
== NULL
)
1037 m_unread
= malloc(size
);
1042 tmp
= malloc(m_unrd_size
+ size
);
1043 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1049 m_unrd_size
+= size
;
1051 memcpy(m_unread
, buffer
, size
);
1054 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1059 if (size
> (m_unrd_size
-m_unrd_cur
))
1060 size
= m_unrd_size
-m_unrd_cur
;
1062 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1067 if (m_unrd_size
== m_unrd_cur
)
1080 // ==========================================================================
1082 // ==========================================================================
1084 // --------------------------------------------------------------------------
1086 // --------------------------------------------------------------------------
1088 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1089 wxSocketFlags flags
)
1090 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1092 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1094 m_socket
= GSocket_new();
1098 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1102 // Setup the socket as server
1104 m_socket
->SetLocal(addr_man
.GetAddress());
1106 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1107 m_socket
->SetReusable();
1110 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1115 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1119 m_socket
->SetTimeout(m_timeout
* 1000);
1120 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1121 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1122 wx_socket_callback
, (char *)this);
1125 // --------------------------------------------------------------------------
1127 // --------------------------------------------------------------------------
1129 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1131 GSocket
*child_socket
;
1136 // If wait == false, then the call should be nonblocking.
1137 // When we are finished, we put the socket to blocking mode
1141 m_socket
->SetNonBlocking(1);
1143 child_socket
= m_socket
->WaitConnection();
1146 m_socket
->SetNonBlocking(0);
1151 sock
.m_type
= wxSOCKET_BASE
;
1152 sock
.m_socket
= child_socket
;
1153 sock
.m_connected
= true;
1155 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1156 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1157 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1158 wx_socket_callback
, (char *)&sock
);
1163 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1165 wxSocketBase
* sock
= new wxSocketBase();
1167 sock
->SetFlags(m_flags
);
1169 if (!AcceptWith(*sock
, wait
))
1178 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1180 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1183 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1185 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1187 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1195 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1198 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1200 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1208 bool wxSocketBase::SetLocal(wxIPV4address
& local
)
1210 GAddress
* la
= local
.GetAddress();
1212 // If the address is valid, save it for use when we call Connect
1213 if (la
&& la
->m_addr
)
1215 m_localAddress
= local
;
1223 // ==========================================================================
1225 // ==========================================================================
1227 // --------------------------------------------------------------------------
1229 // --------------------------------------------------------------------------
1231 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1232 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1236 wxSocketClient::~wxSocketClient()
1240 // --------------------------------------------------------------------------
1242 // --------------------------------------------------------------------------
1244 bool wxSocketClient::DoConnect(wxSockAddress
& addr_man
, wxSockAddress
* local
, bool wait
)
1250 // Shutdown and destroy the socket
1255 m_socket
= GSocket_new();
1256 m_connected
= false;
1257 m_establishing
= false;
1262 m_socket
->SetTimeout(m_timeout
* 1000);
1263 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1264 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1265 wx_socket_callback
, (char *)this);
1267 // If wait == false, then the call should be nonblocking.
1268 // When we are finished, we put the socket to blocking mode
1272 m_socket
->SetNonBlocking(1);
1274 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1275 if (GetFlags() & wxSOCKET_REUSEADDR
)
1277 m_socket
->SetReusable();
1280 // If no local address was passed and one has been set, use the one that was Set
1281 if (!local
&& m_localAddress
.GetAddress())
1283 local
= &m_localAddress
;
1286 // Bind to the local IP address and port, when provided
1289 GAddress
* la
= local
->GetAddress();
1291 if (la
&& la
->m_addr
)
1292 m_socket
->SetLocal(la
);
1295 m_socket
->SetPeer(addr_man
.GetAddress());
1296 err
= m_socket
->Connect(GSOCK_STREAMED
);
1299 m_socket
->SetNonBlocking(0);
1301 if (err
!= GSOCK_NOERROR
)
1303 if (err
== GSOCK_WOULDBLOCK
)
1304 m_establishing
= true;
1313 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1315 return (DoConnect(addr_man
, NULL
, wait
));
1318 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, wxSockAddress
& local
, bool wait
)
1320 return (DoConnect(addr_man
, &local
, wait
));
1323 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1325 if (m_connected
) // Already connected
1328 if (!m_establishing
|| !m_socket
) // No connection in progress
1331 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1335 // ==========================================================================
1337 // ==========================================================================
1339 /* NOTE: experimental stuff - might change */
1341 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1342 wxSocketFlags flags
)
1343 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1345 // Create the socket
1346 m_socket
= GSocket_new();
1350 wxFAIL_MSG( _T("datagram socket not new'd") );
1353 // Setup the socket as non connection oriented
1354 m_socket
->SetLocal(addr
.GetAddress());
1355 if( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1362 // Initialize all stuff
1363 m_connected
= false;
1364 m_establishing
= false;
1365 m_socket
->SetTimeout( m_timeout
);
1366 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1367 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1368 wx_socket_callback
, (char*)this );
1371 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1380 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1384 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1386 m_socket
->SetPeer(addr
.GetAddress());
1391 // ==========================================================================
1393 // ==========================================================================
1395 class wxSocketModule
: public wxModule
1398 virtual bool OnInit()
1400 // wxSocketBase will call GSocket_Init() itself when/if needed
1404 virtual void OnExit()
1406 if ( wxSocketBase::IsInitialized() )
1407 wxSocketBase::Shutdown();
1411 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1414 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)