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/module.h"
39 #include "wx/apptrait.h"
40 #include "wx/sckaddr.h"
41 #include "wx/stopwatch.h"
42 #include "wx/thread.h"
43 #include "wx/evtloop.h"
45 // DLL options compatibility check:
47 WX_CHECK_BUILD_OPTIONS("wxNet")
49 // --------------------------------------------------------------------------
50 // macros and constants
51 // --------------------------------------------------------------------------
54 #define MAX_DISCARD_SIZE (10 * 1024)
56 #define wxTRACE_Socket _T("wxSocket")
58 // --------------------------------------------------------------------------
60 // --------------------------------------------------------------------------
62 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
63 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
64 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
65 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
66 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
68 // --------------------------------------------------------------------------
70 // --------------------------------------------------------------------------
72 class wxSocketState
: public wxObject
75 wxSocketFlags m_flags
;
76 wxSocketEventFlags m_eventmask
;
81 wxSocketState() : wxObject() {}
83 DECLARE_NO_COPY_CLASS(wxSocketState
)
86 // ============================================================================
88 // ============================================================================
90 GSocketManager
*GSocketManager::ms_manager
= NULL
;
93 void GSocketManager::Set(GSocketManager
*manager
)
95 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
101 void GSocketManager::Init()
103 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
106 Details: Initialize() creates a hidden window as a sink for socket
107 events, such as 'read completed'. wxMSW has only one message loop
108 for the main thread. If Initialize is called in a secondary thread,
109 the socket window will be created for the secondary thread, but
110 since there is no message loop on this thread, it will never
111 receive events and all socket operations will time out.
112 BTW, the main thread must not be stopped using sleep or block
113 on a semaphore (a bad idea in any case) or socket operations
116 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
117 the main thread. Because secondary threads do not have run loops,
118 adding event notifications to the "Current" loop would have no
119 effect at all, events would never fire.
121 wxASSERT_MSG( wxIsMainThread(),
122 "sockets must be initialized from the main thread" );
124 wxAppConsole
* const app
= wxAppConsole::GetInstance();
125 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
127 ms_manager
= app
->GetTraits()->GetSocketManager();
130 // ==========================================================================
132 // ==========================================================================
134 // --------------------------------------------------------------------------
135 // Initialization and shutdown
136 // --------------------------------------------------------------------------
138 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
139 // to m_countInit with a crit section
140 size_t wxSocketBase::m_countInit
= 0;
142 bool wxSocketBase::IsInitialized()
144 return m_countInit
> 0;
147 bool wxSocketBase::Initialize()
149 if ( !m_countInit
++ )
151 if ( !GSocket_Init() )
162 void wxSocketBase::Shutdown()
164 // we should be initialized
165 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
166 if ( --m_countInit
== 0 )
172 // --------------------------------------------------------------------------
174 // --------------------------------------------------------------------------
176 void wxSocketBase::Init()
179 m_type
= wxSOCKET_UNINIT
;
191 m_beingDeleted
= false;
205 if ( !IsInitialized() )
207 // this Initialize() will be undone by wxSocketModule::OnExit(), all
208 // the other calls to it should be matched by a call to Shutdown()
213 wxSocketBase::wxSocketBase()
218 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
226 wxSocketBase::~wxSocketBase()
228 // Just in case the app called Destroy() *and* then deleted the socket
229 // immediately: don't leave dangling pointers.
230 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
232 traits
->RemoveFromPendingDelete(this);
234 // Shutdown and close the socket
238 // Destroy the GSocket object
242 // Free the pushback buffer
247 bool wxSocketBase::Destroy()
249 // Delayed destruction: the socket will be deleted during the next idle
250 // loop iteration. This ensures that all pending events have been
252 m_beingDeleted
= true;
254 // Shutdown and close the socket
257 // Supress events from now on
260 // schedule this object for deletion
261 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
264 // let the traits object decide what to do with us
265 traits
->ScheduleForDestroy(this);
267 else // no app or no traits
269 // in wxBase we might have no app object at all, don't leak memory
276 // --------------------------------------------------------------------------
278 // --------------------------------------------------------------------------
280 // The following IO operations update m_error and m_lcount:
281 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
283 // TODO: Should Connect, Accept and AcceptWith update m_error?
285 bool wxSocketBase::Close()
287 // Interrupt pending waits
293 m_socket
->UnsetCallback(
297 GSOCK_CONNECTION_FLAG
300 // Shutdown the connection
301 m_socket
->Shutdown();
305 m_establishing
= false;
309 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
314 m_lcount
= _Read(buffer
, nbytes
);
316 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
317 if (m_flags
& wxSOCKET_WAITALL
)
318 m_error
= (m_lcount
!= nbytes
);
320 m_error
= (m_lcount
== 0);
322 // Allow read events from now on
328 wxUint32
wxSocketBase::_Read(void* buffer_
, wxUint32 nbytes
)
330 char *buffer
= (char *)buffer_
;
334 // Try the pushback buffer first
335 total
= GetPushback(buffer
, nbytes
, false);
337 buffer
= (char *)buffer
+ total
;
339 // Return now in one of the following cases:
340 // - the socket is invalid,
341 // - we got all the data
346 // Possible combinations (they are checked in this order)
348 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
353 if (m_flags
& wxSOCKET_NOWAIT
)
355 m_socket
->SetNonBlocking(1);
356 ret
= m_socket
->Read(buffer
, nbytes
);
357 m_socket
->SetNonBlocking(0);
364 else // blocking socket
368 // dispatch events unless disabled
369 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
372 ret
= m_socket
->Read(buffer
, nbytes
);
375 // for connection-oriented (e.g. TCP) sockets we can only read
376 // 0 bytes if the other end has been closed, and for
377 // connectionless ones (UDP) this flag doesn't make sense
378 // anyhow so we can set it to true too without doing any harm
385 // this will be always interpreted as error by Read()
391 // if wxSOCKET_WAITALL is not set, we can leave now as we did read
393 if ( !(m_flags
& wxSOCKET_WAITALL
) )
396 // otherwise check if read the maximal requested amount of data
401 // we didn't, so continue reading
402 buffer
= (char *)buffer
+ ret
;
409 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
411 wxUint32 len
, len2
, sig
, total
;
416 unsigned char sig
[4];
417 unsigned char len
[4];
426 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
428 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
431 sig
= (wxUint32
)msg
.sig
[0];
432 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
433 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
434 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
436 if (sig
!= 0xfeeddead)
438 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
442 len
= (wxUint32
)msg
.len
[0];
443 len
|= (wxUint32
)(msg
.len
[1] << 8);
444 len
|= (wxUint32
)(msg
.len
[2] << 16);
445 len
|= (wxUint32
)(msg
.len
[3] << 24);
455 // Don't attempt to read if the msg was zero bytes long.
458 total
= _Read(buffer
, len
);
466 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
469 // NOTE: discarded bytes don't add to m_lcount.
472 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
473 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
474 len2
-= (wxUint32
)discard_len
;
476 while ((discard_len
> 0) && len2
);
478 delete [] discard_buffer
;
483 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
486 sig
= (wxUint32
)msg
.sig
[0];
487 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
488 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
489 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
491 if (sig
!= 0xdeadfeed)
493 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
509 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
514 m_lcount
= _Read(buffer
, nbytes
);
515 Pushback(buffer
, m_lcount
);
517 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
518 if (m_flags
& wxSOCKET_WAITALL
)
519 m_error
= (m_lcount
!= nbytes
);
521 m_error
= (m_lcount
== 0);
523 // Allow read events again
529 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
534 m_lcount
= _Write(buffer
, nbytes
);
536 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
537 if (m_flags
& wxSOCKET_WAITALL
)
538 m_error
= (m_lcount
!= nbytes
);
540 m_error
= (m_lcount
== 0);
542 // Allow write events again
548 wxUint32
wxSocketBase::_Write(const void *buffer_
, wxUint32 nbytes
)
550 const char *buffer
= (const char *)buffer_
;
554 // If the socket is invalid or parameters are ill, return immediately
555 if (!m_socket
|| !buffer
|| !nbytes
)
558 // Possible combinations (they are checked in this order)
560 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
565 if (m_flags
& wxSOCKET_NOWAIT
)
567 m_socket
->SetNonBlocking(1);
568 ret
= m_socket
->Write(buffer
, nbytes
);
569 m_socket
->SetNonBlocking(0);
574 else // blocking socket
578 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
581 ret
= m_socket
->Write(buffer
, nbytes
);
583 // see comments for similar logic for ret handling in _Read()
596 if ( !(m_flags
& wxSOCKET_WAITALL
) )
603 buffer
= (const char *)buffer
+ ret
;
610 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
616 unsigned char sig
[4];
617 unsigned char len
[4];
625 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
627 msg
.sig
[0] = (unsigned char) 0xad;
628 msg
.sig
[1] = (unsigned char) 0xde;
629 msg
.sig
[2] = (unsigned char) 0xed;
630 msg
.sig
[3] = (unsigned char) 0xfe;
632 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
633 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
634 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
635 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
637 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
640 total
= _Write(buffer
, nbytes
);
645 msg
.sig
[0] = (unsigned char) 0xed;
646 msg
.sig
[1] = (unsigned char) 0xfe;
647 msg
.sig
[2] = (unsigned char) 0xad;
648 msg
.sig
[3] = (unsigned char) 0xde;
652 msg
.len
[3] = (char) 0;
654 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
668 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
671 Pushback(buffer
, nbytes
);
679 wxSocketBase
& wxSocketBase::Discard()
681 char *buffer
= new char[MAX_DISCARD_SIZE
];
688 SetFlags(wxSOCKET_NOWAIT
);
692 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
695 while (ret
== MAX_DISCARD_SIZE
);
701 // Allow read events again
707 // --------------------------------------------------------------------------
709 // --------------------------------------------------------------------------
711 // All Wait functions poll the socket using GSocket_Select() to
712 // check for the specified combination of conditions, until one
713 // of these conditions become true, an error occurs, or the
714 // timeout elapses. The polling loop runs the event loop so that
715 // this won't block the GUI.
718 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
720 wxCHECK_MSG( m_socket
, false, "can't wait on invalid socket" );
722 // This can be set to true from Interrupt() to exit this function a.s.a.p.
726 // Use either the provided timeout or the default timeout value associated
729 // TODO: allow waiting forever, see #9443
730 const long timeout
= seconds
== -1 ? m_timeout
* 1000
731 : seconds
* 1000 + milliseconds
;
732 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
734 // Get the active event loop which we'll use for the message dispatching
735 // when running in the main thread
736 wxEventLoopBase
*eventLoop
;
737 if ( wxIsMainThread() )
739 eventLoop
= wxEventLoop::GetActive();
742 wxASSERT_MSG( eventLoop
,
743 "Sockets won't work without a running event loop" );
746 else // in worker thread
748 // We never dispatch messages from threads other than the main one.
752 // Wait in an active polling loop: notice that the loop is executed at
753 // least once, even if timeout is 0 (i.e. polling).
754 bool gotEvent
= false;
757 // We always stop waiting when the connection is lost as it doesn't
758 // make sense to continue further, even if GSOCK_LOST_FLAG is not
759 // specified in flags to wait for.
760 const GSocketEventFlags
761 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
763 // Incoming connection (server) or connection established (client)?
764 if ( result
& GSOCK_CONNECTION_FLAG
)
767 m_establishing
= false;
772 // Data available or output buffer ready?
773 if ( (result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
) )
780 if ( result
& GSOCK_LOST_FLAG
)
783 m_establishing
= false;
784 if ( flags
& GSOCK_LOST_FLAG
)
793 const wxMilliClock_t timeNow
= wxGetLocalTimeMillis();
794 if ( timeNow
>= timeEnd
)
799 // Dispatch the events when we run in the main thread and have an
800 // active event loop: without this sockets don't work at all under
801 // MSW as socket flags are only updated when socket messages are
803 if ( eventLoop
->Pending() )
804 eventLoop
->Dispatch();
807 else // no event loop or waiting in another thread
809 // We're busy waiting but at least give up the rest of our current
813 #endif // wxUSE_THREADS
819 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
821 return DoWait(seconds
, milliseconds
,
824 GSOCK_CONNECTION_FLAG
|
829 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
831 // Check pushback buffer before entering DoWait
835 // Note that GSOCK_INPUT_LOST has to be explicitly passed to DoWait
836 // because of the semantics of WaitForRead: a return value of true means
837 // that a GSocket_Read call will return immediately, not that there is
838 // actually data to read.
839 return DoWait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
| GSOCK_LOST_FLAG
);
843 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
845 return DoWait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
| GSOCK_LOST_FLAG
);
848 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
850 return DoWait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
853 // --------------------------------------------------------------------------
855 // --------------------------------------------------------------------------
858 // Get local or peer address
861 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
868 peer
= m_socket
->GetPeer();
870 // copying a null address would just trigger an assert anyway
875 addr_man
.SetAddress(peer
);
876 GAddress_destroy(peer
);
881 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
888 local
= m_socket
->GetLocal();
889 addr_man
.SetAddress(local
);
890 GAddress_destroy(local
);
896 // Save and restore socket state
899 void wxSocketBase::SaveState()
901 wxSocketState
*state
;
903 state
= new wxSocketState();
905 state
->m_flags
= m_flags
;
906 state
->m_notify
= m_notify
;
907 state
->m_eventmask
= m_eventmask
;
908 state
->m_clientData
= m_clientData
;
910 m_states
.Append(state
);
913 void wxSocketBase::RestoreState()
915 wxList::compatibility_iterator node
;
916 wxSocketState
*state
;
918 node
= m_states
.GetLast();
922 state
= (wxSocketState
*)node
->GetData();
924 m_flags
= state
->m_flags
;
925 m_notify
= state
->m_notify
;
926 m_eventmask
= state
->m_eventmask
;
927 m_clientData
= state
->m_clientData
;
929 m_states
.Erase(node
);
937 void wxSocketBase::SetTimeout(long seconds
)
942 m_socket
->SetTimeout(m_timeout
* 1000);
945 void wxSocketBase::SetFlags(wxSocketFlags flags
)
951 // --------------------------------------------------------------------------
953 // --------------------------------------------------------------------------
955 // A note on how events are processed, which is probably the most
956 // difficult thing to get working right while keeping the same API
957 // and functionality for all platforms.
959 // When GSocket detects an event, it calls wx_socket_callback, which in
960 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
961 // object. OnRequest does some housekeeping, and if the event is to be
962 // propagated to the user, it creates a new wxSocketEvent object and
963 // posts it. The event is not processed immediately, but delayed with
964 // AddPendingEvent instead. This is necessary in order to decouple the
965 // event processing from wx_socket_callback; otherwise, subsequent IO
966 // calls made from the user event handler would fail, as gtk callbacks
967 // are not reentrant.
969 // Note that, unlike events, user callbacks (now deprecated) are _not_
970 // decoupled from wx_socket_callback and thus they suffer from a variety
971 // of problems. Avoid them where possible and use events instead.
974 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
975 GSocketEvent notification
,
978 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
980 sckobj
->OnRequest((wxSocketNotify
) notification
);
983 void wxSocketBase::OnRequest(wxSocketNotify notification
)
987 case wxSOCKET_CONNECTION
:
988 m_establishing
= false;
992 // If we are in the middle of a R/W operation, do not
993 // propagate events to users. Also, filter 'late' events
994 // which are no longer valid.
997 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
1001 case wxSOCKET_OUTPUT
:
1002 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
1007 m_connected
= false;
1008 m_establishing
= false;
1012 // Schedule the event
1014 wxSocketEventFlags flag
= 0;
1016 switch (notification
)
1018 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
1019 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
1020 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
1021 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
1023 wxLogWarning(_("wxSocket: unknown event!."));
1027 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1031 wxSocketEvent
event(m_id
);
1032 event
.m_event
= notification
;
1033 event
.m_clientData
= m_clientData
;
1034 event
.SetEventObject(this);
1036 m_handler
->AddPendingEvent(event
);
1041 void wxSocketBase::Notify(bool notify
)
1045 m_socket
->Notify(notify
);
1048 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1050 m_eventmask
= flags
;
1053 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1055 m_handler
= &handler
;
1059 // --------------------------------------------------------------------------
1061 // --------------------------------------------------------------------------
1063 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1067 if (m_unread
== NULL
)
1068 m_unread
= malloc(size
);
1073 tmp
= malloc(m_unrd_size
+ size
);
1074 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1080 m_unrd_size
+= size
;
1082 memcpy(m_unread
, buffer
, size
);
1085 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1090 if (size
> (m_unrd_size
-m_unrd_cur
))
1091 size
= m_unrd_size
-m_unrd_cur
;
1093 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1098 if (m_unrd_size
== m_unrd_cur
)
1111 // ==========================================================================
1113 // ==========================================================================
1115 // --------------------------------------------------------------------------
1117 // --------------------------------------------------------------------------
1119 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1120 wxSocketFlags flags
)
1121 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1123 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1125 m_socket
= GSocket_new();
1129 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1133 // Setup the socket as server
1134 m_socket
->Notify(m_notify
);
1135 m_socket
->SetLocal(addr_man
.GetAddress());
1137 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1138 m_socket
->SetReusable();
1140 if (GetFlags() & wxSOCKET_BROADCAST
) {
1141 m_socket
->SetBroadcast();
1143 if (GetFlags() & wxSOCKET_NOBIND
) {
1144 m_socket
->DontDoBind();
1147 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1152 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1156 m_socket
->SetTimeout(m_timeout
* 1000);
1157 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1158 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1159 wx_socket_callback
, (char *)this);
1161 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_socket
->m_fd
);
1164 // --------------------------------------------------------------------------
1166 // --------------------------------------------------------------------------
1168 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1170 GSocket
*child_socket
;
1175 // If wait == false, then the call should be nonblocking.
1176 // When we are finished, we put the socket to blocking mode
1180 m_socket
->SetNonBlocking(1);
1182 child_socket
= m_socket
->WaitConnection();
1185 m_socket
->SetNonBlocking(0);
1190 sock
.m_type
= wxSOCKET_BASE
;
1191 sock
.m_socket
= child_socket
;
1192 sock
.m_connected
= true;
1194 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1195 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1196 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1197 wx_socket_callback
, (char *)&sock
);
1202 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1204 wxSocketBase
* sock
= new wxSocketBase();
1206 sock
->SetFlags(m_flags
);
1208 if (!AcceptWith(*sock
, wait
))
1217 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1219 return DoWait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1222 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1224 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1226 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1234 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1237 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1239 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1247 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1249 GAddress
* la
= local
.GetAddress();
1251 // If the address is valid, save it for use when we call Connect
1252 if (la
&& la
->m_addr
)
1254 m_localAddress
= local
;
1262 // ==========================================================================
1264 // ==========================================================================
1266 // --------------------------------------------------------------------------
1268 // --------------------------------------------------------------------------
1270 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1271 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1273 m_initialRecvBufferSize
=
1274 m_initialSendBufferSize
= -1;
1277 wxSocketClient::~wxSocketClient()
1281 // --------------------------------------------------------------------------
1283 // --------------------------------------------------------------------------
1285 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1286 const wxSockAddress
* local
,
1293 // Shutdown and destroy the socket
1298 m_socket
= GSocket_new();
1299 m_connected
= false;
1300 m_establishing
= false;
1305 m_socket
->SetTimeout(m_timeout
* 1000);
1306 m_socket
->SetCallback(
1310 GSOCK_CONNECTION_FLAG
,
1315 // If wait == false, then the call should be nonblocking. When we are
1316 // finished, we put the socket to blocking mode again.
1319 m_socket
->SetNonBlocking(1);
1321 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1322 if (GetFlags() & wxSOCKET_REUSEADDR
)
1324 m_socket
->SetReusable();
1326 if (GetFlags() & wxSOCKET_BROADCAST
)
1328 m_socket
->SetBroadcast();
1330 if (GetFlags() & wxSOCKET_NOBIND
)
1332 m_socket
->DontDoBind();
1335 // If no local address was passed and one has been set, use the one that was Set
1336 if (!local
&& m_localAddress
.GetAddress())
1338 local
= &m_localAddress
;
1341 // Bind to the local IP address and port, when provided
1344 GAddress
* la
= local
->GetAddress();
1346 if (la
&& la
->m_addr
)
1347 m_socket
->SetLocal(la
);
1350 #if defined(__WXMSW__) || defined(__WXGTK__)
1351 m_socket
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1354 m_socket
->SetPeer(addr_man
.GetAddress());
1355 err
= m_socket
->Connect(GSOCK_STREAMED
);
1357 //this will register for callbacks - must be called after m_socket->m_fd was initialized
1358 m_socket
->Notify(m_notify
);
1361 m_socket
->SetNonBlocking(0);
1363 if (err
!= GSOCK_NOERROR
)
1365 if (err
== GSOCK_WOULDBLOCK
)
1366 m_establishing
= true;
1375 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1377 return DoConnect(addr_man
, NULL
, wait
);
1380 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1381 const wxSockAddress
& local
,
1384 return DoConnect(addr_man
, &local
, wait
);
1387 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1391 // this happens if the initial attempt to connect succeeded without
1396 wxCHECK_MSG( m_establishing
&& m_socket
, false,
1397 "No connection establishment attempt in progress" );
1399 // we must specify GSOCK_LOST_FLAG here explicitly because we must return
1400 // true if the connection establishment process is finished, whether it is
1401 // over because we successfully connected or because we were not able to
1403 return DoWait(seconds
, milliseconds
,
1404 GSOCK_CONNECTION_FLAG
| GSOCK_LOST_FLAG
);
1407 // ==========================================================================
1409 // ==========================================================================
1411 /* NOTE: experimental stuff - might change */
1413 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1414 wxSocketFlags flags
)
1415 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1417 // Create the socket
1418 m_socket
= GSocket_new();
1422 wxFAIL_MSG( _T("datagram socket not new'd") );
1425 m_socket
->Notify(m_notify
);
1426 // Setup the socket as non connection oriented
1427 m_socket
->SetLocal(addr
.GetAddress());
1428 if (flags
& wxSOCKET_REUSEADDR
)
1430 m_socket
->SetReusable();
1432 if (GetFlags() & wxSOCKET_BROADCAST
)
1434 m_socket
->SetBroadcast();
1436 if (GetFlags() & wxSOCKET_NOBIND
)
1438 m_socket
->DontDoBind();
1440 if ( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1447 // Initialize all stuff
1448 m_connected
= false;
1449 m_establishing
= false;
1450 m_socket
->SetTimeout( m_timeout
);
1451 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1452 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1453 wx_socket_callback
, (char*)this );
1456 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1465 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1469 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1471 m_socket
->SetPeer(addr
.GetAddress());
1476 // ==========================================================================
1478 // ==========================================================================
1480 class wxSocketModule
: public wxModule
1483 virtual bool OnInit()
1485 // wxSocketBase will call GSocket_Init() itself when/if needed
1489 virtual void OnExit()
1491 if ( wxSocketBase::IsInitialized() )
1492 wxSocketBase::Shutdown();
1496 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1499 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1501 #endif // wxUSE_SOCKETS