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 #include "wx/private/fd.h"
46 #include "wx/private/socket.h"
48 // DLL options compatibility check:
50 WX_CHECK_BUILD_OPTIONS("wxNet")
52 // --------------------------------------------------------------------------
53 // macros and constants
54 // --------------------------------------------------------------------------
57 #define MAX_DISCARD_SIZE (10 * 1024)
59 #define wxTRACE_Socket _T("wxSocket")
61 // --------------------------------------------------------------------------
63 // --------------------------------------------------------------------------
65 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
66 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
67 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
68 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
69 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
71 // --------------------------------------------------------------------------
73 // --------------------------------------------------------------------------
75 class wxSocketState
: public wxObject
78 wxSocketFlags m_flags
;
79 wxSocketEventFlags m_eventmask
;
84 wxSocketState() : wxObject() {}
86 DECLARE_NO_COPY_CLASS(wxSocketState
)
89 // Conditionally make the socket non-blocking for the lifetime of this object.
90 class wxSocketUnblocker
93 wxSocketUnblocker(GSocket
*socket
, bool unblock
= true)
98 m_socket
->SetNonBlocking(true);
104 m_socket
->SetNonBlocking(false);
108 GSocket
* const m_socket
;
111 DECLARE_NO_COPY_CLASS(wxSocketUnblocker
)
114 // ============================================================================
116 // ============================================================================
118 GSocketManager
*GSocketManager::ms_manager
= NULL
;
121 void GSocketManager::Set(GSocketManager
*manager
)
123 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
125 ms_manager
= manager
;
129 void GSocketManager::Init()
131 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
134 Details: Initialize() creates a hidden window as a sink for socket
135 events, such as 'read completed'. wxMSW has only one message loop
136 for the main thread. If Initialize is called in a secondary thread,
137 the socket window will be created for the secondary thread, but
138 since there is no message loop on this thread, it will never
139 receive events and all socket operations will time out.
140 BTW, the main thread must not be stopped using sleep or block
141 on a semaphore (a bad idea in any case) or socket operations
144 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
145 the main thread. Because secondary threads do not have run loops,
146 adding event notifications to the "Current" loop would have no
147 effect at all, events would never fire.
149 wxASSERT_MSG( wxIsMainThread(),
150 "sockets must be initialized from the main thread" );
152 wxAppConsole
* const app
= wxAppConsole::GetInstance();
153 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
155 ms_manager
= app
->GetTraits()->GetSocketManager();
158 // ==========================================================================
160 // ==========================================================================
163 GSocket
*GSocketBase::Create(wxSocketBase
& wxsocket
)
165 GSocket
* const newsocket
= new GSocket(wxsocket
);
166 if ( !GSocketManager::Get()->Init_Socket(newsocket
) )
175 GSocketBase::GSocketBase(wxSocketBase
& wxsocket
)
176 : m_wxsocket(&wxsocket
)
178 m_fd
= INVALID_SOCKET
;
182 m_error
= GSOCK_NOERROR
;
185 m_non_blocking
= false;
187 SetTimeout(wxsocket
.GetTimeout() * 1000);
189 m_establishing
= false;
193 m_initialRecvBufferSize
= -1;
194 m_initialSendBufferSize
= -1;
197 GSocketBase::~GSocketBase()
199 if (m_fd
!= INVALID_SOCKET
)
203 GAddress_destroy(m_local
);
206 GAddress_destroy(m_peer
);
208 // cast is ok as all GSocketBase objects we have in our code are really
210 GSocketManager::Get()->Destroy_Socket(static_cast<GSocket
*>(this));
213 void GSocketBase::Close()
215 if ( m_fd
!= INVALID_SOCKET
)
217 GSocketManager::Get()->Close_Socket(static_cast<GSocket
*>(this));
218 m_fd
= INVALID_SOCKET
;
223 * Disallow further read/write operations on this socket, close
224 * the fd and disable all callbacks.
226 void GSocketBase::Shutdown()
228 if ( m_fd
!= INVALID_SOCKET
)
230 shutdown(m_fd
, 1 /* SD_SEND */);
234 m_detected
= GSOCK_LOST_FLAG
;
237 /* GSocket_SetTimeout:
238 * Sets the timeout for blocking calls. Time is expressed in
241 void GSocketBase::SetTimeout(unsigned long millis
)
243 m_timeout
.tv_sec
= (millis
/ 1000);
244 m_timeout
.tv_usec
= (millis
% 1000) * 1000;
247 void GSocketBase::NotifyOnStateChange(GSocketEvent event
)
249 // GSocketEvent and wxSocketNotify enums have the same elements with the
251 m_wxsocket
->OnRequest(static_cast<wxSocketNotify
>(event
));
254 /* Address handling */
260 * Set or get the local or peer address for this socket. The 'set'
261 * functions return GSOCK_NOERROR on success, an error code otherwise.
262 * The 'get' functions return a pointer to a GAddress object on success,
263 * or NULL otherwise, in which case they set the error code of the
264 * corresponding GSocket.
267 * GSOCK_INVSOCK - the socket is not valid.
268 * GSOCK_INVADDR - the address is not valid.
270 GSocketError
GSocketBase::SetLocal(GAddress
*address
)
272 /* the socket must be initialized, or it must be a server */
273 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
275 m_error
= GSOCK_INVSOCK
;
276 return GSOCK_INVSOCK
;
280 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
282 m_error
= GSOCK_INVADDR
;
283 return GSOCK_INVADDR
;
287 GAddress_destroy(m_local
);
289 m_local
= GAddress_copy(address
);
291 return GSOCK_NOERROR
;
294 GSocketError
GSocketBase::SetPeer(GAddress
*address
)
297 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
299 m_error
= GSOCK_INVADDR
;
300 return GSOCK_INVADDR
;
304 GAddress_destroy(m_peer
);
306 m_peer
= GAddress_copy(address
);
308 return GSOCK_NOERROR
;
311 GAddress
*GSocketBase::GetLocal()
315 WX_SOCKLEN_T size
= sizeof(addr
);
318 /* try to get it from the m_local var first */
320 return GAddress_copy(m_local
);
322 /* else, if the socket is initialized, try getsockname */
323 if (m_fd
== INVALID_SOCKET
)
325 m_error
= GSOCK_INVSOCK
;
329 if (getsockname(m_fd
, (sockaddr
*)&addr
, &size
) == SOCKET_ERROR
)
331 m_error
= GSOCK_IOERR
;
335 /* got a valid address from getsockname, create a GAddress object */
336 if ((address
= GAddress_new()) == NULL
)
338 m_error
= GSOCK_MEMERR
;
342 if ((err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
)) != GSOCK_NOERROR
)
344 GAddress_destroy(address
);
352 GAddress
*GSocketBase::GetPeer()
354 /* try to get it from the m_peer var */
356 return GAddress_copy(m_peer
);
361 // ==========================================================================
363 // ==========================================================================
365 // --------------------------------------------------------------------------
366 // Initialization and shutdown
367 // --------------------------------------------------------------------------
369 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
370 // to m_countInit with a crit section
371 size_t wxSocketBase::m_countInit
= 0;
373 bool wxSocketBase::IsInitialized()
375 return m_countInit
> 0;
378 bool wxSocketBase::Initialize()
380 if ( !m_countInit
++ )
382 if ( !GSocket_Init() )
393 void wxSocketBase::Shutdown()
395 // we should be initialized
396 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
397 if ( --m_countInit
== 0 )
403 // --------------------------------------------------------------------------
405 // --------------------------------------------------------------------------
407 void wxSocketBase::Init()
410 m_type
= wxSOCKET_UNINIT
;
422 m_beingDeleted
= false;
436 if ( !IsInitialized() )
438 // this Initialize() will be undone by wxSocketModule::OnExit(), all
439 // the other calls to it should be matched by a call to Shutdown()
444 wxSocketBase::wxSocketBase()
449 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
458 wxSocketBase::~wxSocketBase()
460 // Just in case the app called Destroy() *and* then deleted the socket
461 // immediately: don't leave dangling pointers.
462 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
464 traits
->RemoveFromPendingDelete(this);
466 // Shutdown and close the socket
470 // Destroy the GSocket object
474 // Free the pushback buffer
479 bool wxSocketBase::Destroy()
481 // Delayed destruction: the socket will be deleted during the next idle
482 // loop iteration. This ensures that all pending events have been
484 m_beingDeleted
= true;
486 // Shutdown and close the socket
489 // Supress events from now on
492 // schedule this object for deletion
493 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
496 // let the traits object decide what to do with us
497 traits
->ScheduleForDestroy(this);
499 else // no app or no traits
501 // in wxBase we might have no app object at all, don't leak memory
508 // --------------------------------------------------------------------------
510 // --------------------------------------------------------------------------
512 // The following IO operations update m_error and m_lcount:
513 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
515 // TODO: Should Connect, Accept and AcceptWith update m_error?
517 bool wxSocketBase::Close()
519 // Interrupt pending waits
523 m_socket
->Shutdown();
526 m_establishing
= false;
530 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
535 m_lcount
= DoRead(buffer
, nbytes
);
537 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
538 if (m_flags
& wxSOCKET_WAITALL
)
539 m_error
= (m_lcount
!= nbytes
);
541 m_error
= (m_lcount
== 0);
543 // Allow read events from now on
549 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
551 // We use pointer arithmetic here which doesn't work with void pointers.
552 char *buffer
= static_cast<char *>(buffer_
);
554 // Try the push back buffer first, even before checking whether the socket
555 // is valid to allow reading previously pushed back data from an already
557 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
561 // If it's indeed closed or if read everything, there is nothing more to do.
562 if ( !m_socket
|| !nbytes
)
565 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
568 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
569 // polling the socket and don't block at all.
570 if ( m_flags
& wxSOCKET_NOWAIT
)
572 wxSocketUnblocker
unblock(m_socket
);
573 int ret
= m_socket
->Read(buffer
, nbytes
);
579 else // blocking socket
583 // Wait until socket becomes ready for reading dispatching the GUI
584 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
585 // specified to disable this.
586 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
589 const int ret
= m_socket
->Read(buffer
, nbytes
);
592 // for connection-oriented (e.g. TCP) sockets we can only read
593 // 0 bytes if the other end has been closed, and for
594 // connectionless ones (UDP) this flag doesn't make sense
595 // anyhow so we can set it to true too without doing any harm
602 // this will be always interpreted as error by Read()
608 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
609 // something and we don't need to wait for all nbytes bytes to be
611 if ( !(m_flags
& wxSOCKET_WAITALL
) )
614 // Otherwise continue reading until we do read everything.
626 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
628 wxUint32 len
, len2
, sig
, total
;
633 unsigned char sig
[4];
634 unsigned char len
[4];
643 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
645 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
648 sig
= (wxUint32
)msg
.sig
[0];
649 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
650 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
651 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
653 if (sig
!= 0xfeeddead)
655 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
659 len
= (wxUint32
)msg
.len
[0];
660 len
|= (wxUint32
)(msg
.len
[1] << 8);
661 len
|= (wxUint32
)(msg
.len
[2] << 16);
662 len
|= (wxUint32
)(msg
.len
[3] << 24);
672 // Don't attempt to read if the msg was zero bytes long.
675 total
= DoRead(buffer
, len
);
683 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
686 // NOTE: discarded bytes don't add to m_lcount.
689 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
690 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
691 len2
-= (wxUint32
)discard_len
;
693 while ((discard_len
> 0) && len2
);
695 delete [] discard_buffer
;
700 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
703 sig
= (wxUint32
)msg
.sig
[0];
704 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
705 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
706 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
708 if (sig
!= 0xdeadfeed)
710 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
726 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
731 m_lcount
= DoRead(buffer
, nbytes
);
732 Pushback(buffer
, m_lcount
);
734 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
735 if (m_flags
& wxSOCKET_WAITALL
)
736 m_error
= (m_lcount
!= nbytes
);
738 m_error
= (m_lcount
== 0);
740 // Allow read events again
746 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
751 m_lcount
= DoWrite(buffer
, nbytes
);
753 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
754 if (m_flags
& wxSOCKET_WAITALL
)
755 m_error
= (m_lcount
!= nbytes
);
757 m_error
= (m_lcount
== 0);
759 // Allow write events again
765 // This function is a mirror image of DoRead() except that it doesn't use the
766 // push back buffer, please see comments there
767 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
769 const char *buffer
= static_cast<const char *>(buffer_
);
771 // Return if there is nothing to read or the socket is (already?) closed.
772 if ( !m_socket
|| !nbytes
)
775 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
778 if ( m_flags
& wxSOCKET_NOWAIT
)
780 wxSocketUnblocker
unblock(m_socket
);
781 const int ret
= m_socket
->Write(buffer
, nbytes
);
785 else // blocking socket
789 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
792 const int ret
= m_socket
->Write(buffer
, nbytes
);
803 if ( !(m_flags
& wxSOCKET_WAITALL
) )
817 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
823 unsigned char sig
[4];
824 unsigned char len
[4];
832 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
834 msg
.sig
[0] = (unsigned char) 0xad;
835 msg
.sig
[1] = (unsigned char) 0xde;
836 msg
.sig
[2] = (unsigned char) 0xed;
837 msg
.sig
[3] = (unsigned char) 0xfe;
839 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
840 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
841 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
842 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
844 if (DoWrite(&msg
, sizeof(msg
)) < sizeof(msg
))
847 total
= DoWrite(buffer
, nbytes
);
852 msg
.sig
[0] = (unsigned char) 0xed;
853 msg
.sig
[1] = (unsigned char) 0xfe;
854 msg
.sig
[2] = (unsigned char) 0xad;
855 msg
.sig
[3] = (unsigned char) 0xde;
859 msg
.len
[3] = (char) 0;
861 if ((DoWrite(&msg
, sizeof(msg
))) < sizeof(msg
))
875 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
878 Pushback(buffer
, nbytes
);
886 wxSocketBase
& wxSocketBase::Discard()
888 char *buffer
= new char[MAX_DISCARD_SIZE
];
895 SetFlags(wxSOCKET_NOWAIT
);
899 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
902 while (ret
== MAX_DISCARD_SIZE
);
908 // Allow read events again
914 // --------------------------------------------------------------------------
916 // --------------------------------------------------------------------------
919 * Polls the socket to determine its status. This function will
920 * check for the events specified in the 'flags' parameter, and
921 * it will return a mask indicating which operations can be
922 * performed. This function won't block, regardless of the
923 * mode (blocking | nonblocking) of the socket.
925 GSocketEventFlags
GSocketBase::Select(GSocketEventFlags flags
)
929 GSocketEventFlags result
= 0;
936 return (GSOCK_LOST_FLAG
& flags
);
938 /* Do not use a static struct, Linux can garble it */
943 wxFD_ZERO(&writefds
);
944 wxFD_ZERO(&exceptfds
);
945 wxFD_SET(m_fd
, &readfds
);
946 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
947 wxFD_SET(m_fd
, &writefds
);
948 wxFD_SET(m_fd
, &exceptfds
);
950 /* Check 'sticky' CONNECTION flag first */
951 result
|= GSOCK_CONNECTION_FLAG
& m_detected
;
953 /* If we have already detected a LOST event, then don't try
954 * to do any further processing.
956 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
958 m_establishing
= false;
959 return (GSOCK_LOST_FLAG
& flags
);
963 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
965 /* What to do here? */
966 return (result
& flags
);
969 /* Check for exceptions and errors */
970 if (wxFD_ISSET(m_fd
, &exceptfds
))
972 m_establishing
= false;
973 m_detected
= GSOCK_LOST_FLAG
;
975 /* LOST event: Abort any further processing */
976 return (GSOCK_LOST_FLAG
& flags
);
979 /* Check for readability */
980 if (wxFD_ISSET(m_fd
, &readfds
))
982 result
|= GSOCK_INPUT_FLAG
;
984 if (m_server
&& m_stream
)
986 /* This is a TCP server socket that detected a connection.
987 While the INPUT_FLAG is also set, it doesn't matter on
988 this kind of sockets, as we can only Accept() from them. */
989 m_detected
|= GSOCK_CONNECTION_FLAG
;
993 /* Check for writability */
994 if (wxFD_ISSET(m_fd
, &writefds
))
996 if (m_establishing
&& !m_server
)
999 SOCKOPTLEN_T len
= sizeof(error
);
1000 m_establishing
= false;
1001 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1005 m_detected
= GSOCK_LOST_FLAG
;
1007 /* LOST event: Abort any further processing */
1008 return (GSOCK_LOST_FLAG
& flags
);
1012 m_detected
|= GSOCK_CONNECTION_FLAG
;
1017 result
|= GSOCK_OUTPUT_FLAG
;
1021 return (result
| m_detected
) & flags
;
1024 // All Wait functions poll the socket using GSocket_Select() to
1025 // check for the specified combination of conditions, until one
1026 // of these conditions become true, an error occurs, or the
1027 // timeout elapses. The polling loop runs the event loop so that
1028 // this won't block the GUI.
1031 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1033 wxCHECK_MSG( m_socket
, false, "can't wait on invalid socket" );
1035 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1036 m_interrupt
= false;
1039 // Use either the provided timeout or the default timeout value associated
1040 // with this socket.
1042 // TODO: allow waiting forever, see #9443
1043 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1044 : seconds
* 1000 + milliseconds
;
1045 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1047 // Get the active event loop which we'll use for the message dispatching
1048 // when running in the main thread
1049 wxEventLoopBase
*eventLoop
;
1050 if ( wxIsMainThread() )
1052 eventLoop
= wxEventLoop::GetActive();
1054 else // in worker thread
1056 // We never dispatch messages from threads other than the main one.
1060 // Wait in an active polling loop: notice that the loop is executed at
1061 // least once, even if timeout is 0 (i.e. polling).
1062 bool gotEvent
= false;
1065 // We always stop waiting when the connection is lost as it doesn't
1066 // make sense to continue further, even if GSOCK_LOST_FLAG is not
1067 // specified in flags to wait for.
1068 const GSocketEventFlags
1069 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
1071 // Incoming connection (server) or connection established (client)?
1072 if ( result
& GSOCK_CONNECTION_FLAG
)
1075 m_establishing
= false;
1080 // Data available or output buffer ready?
1081 if ( (result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
) )
1088 if ( result
& GSOCK_LOST_FLAG
)
1090 m_connected
= false;
1091 m_establishing
= false;
1092 if ( flags
& GSOCK_LOST_FLAG
)
1101 const wxMilliClock_t timeNow
= wxGetLocalTimeMillis();
1102 if ( timeNow
>= timeEnd
)
1107 // This function is only called if wxSOCKET_BLOCK flag was not used
1108 // and so we should dispatch the events if there is an event loop
1109 // capable of doing it.
1110 if ( eventLoop
->Pending() )
1111 eventLoop
->Dispatch();
1114 else // no event loop or waiting in another thread
1116 // We're busy waiting but at least give up the rest of our current
1120 #endif // wxUSE_THREADS
1126 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1128 return DoWait(seconds
, milliseconds
,
1131 GSOCK_CONNECTION_FLAG
|
1136 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1138 // Check pushback buffer before entering DoWait
1142 // Note that GSOCK_INPUT_LOST has to be explicitly passed to DoWait
1143 // because of the semantics of WaitForRead: a return value of true means
1144 // that a GSocket_Read call will return immediately, not that there is
1145 // actually data to read.
1146 return DoWait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
| GSOCK_LOST_FLAG
);
1150 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1152 return DoWait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
| GSOCK_LOST_FLAG
);
1155 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1157 return DoWait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
1160 // --------------------------------------------------------------------------
1162 // --------------------------------------------------------------------------
1165 // Get local or peer address
1168 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
1175 peer
= m_socket
->GetPeer();
1177 // copying a null address would just trigger an assert anyway
1182 addr_man
.SetAddress(peer
);
1183 GAddress_destroy(peer
);
1188 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1195 local
= m_socket
->GetLocal();
1196 addr_man
.SetAddress(local
);
1197 GAddress_destroy(local
);
1203 // Save and restore socket state
1206 void wxSocketBase::SaveState()
1208 wxSocketState
*state
;
1210 state
= new wxSocketState();
1212 state
->m_flags
= m_flags
;
1213 state
->m_notify
= m_notify
;
1214 state
->m_eventmask
= m_eventmask
;
1215 state
->m_clientData
= m_clientData
;
1217 m_states
.Append(state
);
1220 void wxSocketBase::RestoreState()
1222 wxList::compatibility_iterator node
;
1223 wxSocketState
*state
;
1225 node
= m_states
.GetLast();
1229 state
= (wxSocketState
*)node
->GetData();
1231 m_flags
= state
->m_flags
;
1232 m_notify
= state
->m_notify
;
1233 m_eventmask
= state
->m_eventmask
;
1234 m_clientData
= state
->m_clientData
;
1236 m_states
.Erase(node
);
1241 // Timeout and flags
1244 void wxSocketBase::SetTimeout(long seconds
)
1246 m_timeout
= seconds
;
1249 m_socket
->SetTimeout(m_timeout
* 1000);
1252 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1254 // Do some sanity checking on the flags used: not all values can be used
1256 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1257 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1258 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1259 "wxSOCKET_NOWAIT doesn't make sense" );
1265 // --------------------------------------------------------------------------
1267 // --------------------------------------------------------------------------
1269 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1271 switch(notification
)
1273 case wxSOCKET_CONNECTION
:
1274 m_establishing
= false;
1278 // If we are in the middle of a R/W operation, do not
1279 // propagate events to users. Also, filter 'late' events
1280 // which are no longer valid.
1282 case wxSOCKET_INPUT
:
1283 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
1287 case wxSOCKET_OUTPUT
:
1288 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
1293 m_connected
= false;
1294 m_establishing
= false;
1298 // Schedule the event
1300 wxSocketEventFlags flag
= 0;
1302 switch (notification
)
1304 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
1305 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
1306 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
1307 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
1309 wxLogWarning(_("wxSocket: unknown event!."));
1313 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1317 wxSocketEvent
event(m_id
);
1318 event
.m_event
= notification
;
1319 event
.m_clientData
= m_clientData
;
1320 event
.SetEventObject(this);
1322 m_handler
->AddPendingEvent(event
);
1327 void wxSocketBase::Notify(bool notify
)
1331 m_socket
->Notify(notify
);
1334 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1336 m_eventmask
= flags
;
1339 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1341 m_handler
= &handler
;
1345 // --------------------------------------------------------------------------
1347 // --------------------------------------------------------------------------
1349 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1353 if (m_unread
== NULL
)
1354 m_unread
= malloc(size
);
1359 tmp
= malloc(m_unrd_size
+ size
);
1360 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1366 m_unrd_size
+= size
;
1368 memcpy(m_unread
, buffer
, size
);
1371 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1373 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1378 if (size
> (m_unrd_size
-m_unrd_cur
))
1379 size
= m_unrd_size
-m_unrd_cur
;
1381 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1386 if (m_unrd_size
== m_unrd_cur
)
1399 // ==========================================================================
1401 // ==========================================================================
1403 // --------------------------------------------------------------------------
1405 // --------------------------------------------------------------------------
1407 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1408 wxSocketFlags flags
)
1409 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1411 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1413 m_socket
= GSocket::Create(*this);
1417 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1421 // Setup the socket as server
1422 m_socket
->Notify(m_notify
);
1423 m_socket
->SetLocal(addr_man
.GetAddress());
1425 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1426 m_socket
->SetReusable();
1428 if (GetFlags() & wxSOCKET_BROADCAST
) {
1429 m_socket
->SetBroadcast();
1431 if (GetFlags() & wxSOCKET_NOBIND
) {
1432 m_socket
->DontDoBind();
1435 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1440 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1444 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_socket
->m_fd
);
1447 // --------------------------------------------------------------------------
1449 // --------------------------------------------------------------------------
1451 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1456 // If wait == false, then the call should be nonblocking.
1457 // When we are finished, we put the socket to blocking mode
1459 wxSocketUnblocker
unblock(m_socket
, !wait
);
1460 sock
.m_socket
= m_socket
->WaitConnection(sock
);
1462 if ( !sock
.m_socket
)
1465 sock
.m_type
= wxSOCKET_BASE
;
1466 sock
.m_connected
= true;
1471 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1473 wxSocketBase
* sock
= new wxSocketBase();
1475 sock
->SetFlags(m_flags
);
1477 if (!AcceptWith(*sock
, wait
))
1486 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1488 return DoWait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1491 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1493 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1495 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1503 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1506 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1508 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1516 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1518 GAddress
* la
= local
.GetAddress();
1520 // If the address is valid, save it for use when we call Connect
1521 if (la
&& la
->m_addr
)
1523 m_localAddress
= local
;
1531 // ==========================================================================
1533 // ==========================================================================
1535 // --------------------------------------------------------------------------
1537 // --------------------------------------------------------------------------
1539 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1540 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1542 m_initialRecvBufferSize
=
1543 m_initialSendBufferSize
= -1;
1546 wxSocketClient::~wxSocketClient()
1550 // --------------------------------------------------------------------------
1552 // --------------------------------------------------------------------------
1554 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1555 const wxSockAddress
* local
,
1560 // Shutdown and destroy the socket
1565 m_socket
= GSocket::Create(*this);
1566 m_connected
= false;
1567 m_establishing
= false;
1572 // If wait == false, then the call should be nonblocking. When we are
1573 // finished, we put the socket to blocking mode again.
1574 wxSocketUnblocker
unblock(m_socket
, !wait
);
1576 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1577 if (GetFlags() & wxSOCKET_REUSEADDR
)
1579 m_socket
->SetReusable();
1581 if (GetFlags() & wxSOCKET_BROADCAST
)
1583 m_socket
->SetBroadcast();
1585 if (GetFlags() & wxSOCKET_NOBIND
)
1587 m_socket
->DontDoBind();
1590 // If no local address was passed and one has been set, use the one that was Set
1591 if (!local
&& m_localAddress
.GetAddress())
1593 local
= &m_localAddress
;
1596 // Bind to the local IP address and port, when provided
1599 GAddress
* la
= local
->GetAddress();
1601 if (la
&& la
->m_addr
)
1602 m_socket
->SetLocal(la
);
1605 #if defined(__WXMSW__) || defined(__WXGTK__)
1606 m_socket
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1609 m_socket
->SetPeer(addr_man
.GetAddress());
1610 const GSocketError err
= m_socket
->Connect(GSOCK_STREAMED
);
1612 //this will register for callbacks - must be called after m_socket->m_fd was initialized
1613 m_socket
->Notify(m_notify
);
1615 if (err
!= GSOCK_NOERROR
)
1617 if (err
== GSOCK_WOULDBLOCK
)
1618 m_establishing
= true;
1627 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1629 return DoConnect(addr_man
, NULL
, wait
);
1632 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1633 const wxSockAddress
& local
,
1636 return DoConnect(addr_man
, &local
, wait
);
1639 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1643 // this happens if the initial attempt to connect succeeded without
1648 wxCHECK_MSG( m_establishing
&& m_socket
, false,
1649 "No connection establishment attempt in progress" );
1651 // we must specify GSOCK_LOST_FLAG here explicitly because we must return
1652 // true if the connection establishment process is finished, whether it is
1653 // over because we successfully connected or because we were not able to
1655 return DoWait(seconds
, milliseconds
,
1656 GSOCK_CONNECTION_FLAG
| GSOCK_LOST_FLAG
);
1659 // ==========================================================================
1661 // ==========================================================================
1663 /* NOTE: experimental stuff - might change */
1665 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1666 wxSocketFlags flags
)
1667 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1669 // Create the socket
1670 m_socket
= GSocket::Create(*this);
1675 m_socket
->Notify(m_notify
);
1676 // Setup the socket as non connection oriented
1677 m_socket
->SetLocal(addr
.GetAddress());
1678 if (flags
& wxSOCKET_REUSEADDR
)
1680 m_socket
->SetReusable();
1682 if (GetFlags() & wxSOCKET_BROADCAST
)
1684 m_socket
->SetBroadcast();
1686 if (GetFlags() & wxSOCKET_NOBIND
)
1688 m_socket
->DontDoBind();
1690 if ( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1697 // Initialize all stuff
1698 m_connected
= false;
1699 m_establishing
= false;
1702 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1711 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1715 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1717 m_socket
->SetPeer(addr
.GetAddress());
1722 // ==========================================================================
1724 // ==========================================================================
1726 class wxSocketModule
: public wxModule
1729 virtual bool OnInit()
1731 // wxSocketBase will call GSocket_Init() itself when/if needed
1735 virtual void OnExit()
1737 if ( wxSocketBase::IsInitialized() )
1738 wxSocketBase::Shutdown();
1742 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1745 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1747 #endif // wxUSE_SOCKETS