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) 1999-2000, Guillermo Rodriguez Garcia
8 // (C) 2008 Vadim Zeitlin
10 // License: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
13 // ==========================================================================
15 // ==========================================================================
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
26 #include "wx/socket.h"
29 #include "wx/object.h"
30 #include "wx/string.h"
37 #include "wx/module.h"
40 #include "wx/apptrait.h"
41 #include "wx/sckaddr.h"
42 #include "wx/stopwatch.h"
43 #include "wx/thread.h"
44 #include "wx/evtloop.h"
46 #include "wx/private/fd.h"
47 #include "wx/private/socket.h"
49 // DLL options compatibility check:
51 WX_CHECK_BUILD_OPTIONS("wxNet")
53 // --------------------------------------------------------------------------
54 // macros and constants
55 // --------------------------------------------------------------------------
58 #define MAX_DISCARD_SIZE (10 * 1024)
60 #define wxTRACE_Socket _T("wxSocket")
62 // --------------------------------------------------------------------------
64 // --------------------------------------------------------------------------
66 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
67 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
68 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
69 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
70 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
72 // --------------------------------------------------------------------------
74 // --------------------------------------------------------------------------
76 class wxSocketState
: public wxObject
79 wxSocketFlags m_flags
;
80 wxSocketEventFlags m_eventmask
;
85 wxSocketState() : wxObject() {}
87 DECLARE_NO_COPY_CLASS(wxSocketState
)
90 // Conditionally make the socket non-blocking for the lifetime of this object.
91 class wxSocketUnblocker
94 wxSocketUnblocker(wxSocketImpl
*socket
, bool unblock
= true)
99 m_impl
->SetNonBlocking(true);
105 m_impl
->SetNonBlocking(false);
109 wxSocketImpl
* const m_impl
;
112 DECLARE_NO_COPY_CLASS(wxSocketUnblocker
)
115 // ============================================================================
117 // ============================================================================
119 wxSocketManager
*wxSocketManager::ms_manager
= NULL
;
122 void wxSocketManager::Set(wxSocketManager
*manager
)
124 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
126 ms_manager
= manager
;
130 void wxSocketManager::Init()
132 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
135 Details: Initialize() creates a hidden window as a sink for socket
136 events, such as 'read completed'. wxMSW has only one message loop
137 for the main thread. If Initialize is called in a secondary thread,
138 the socket window will be created for the secondary thread, but
139 since there is no message loop on this thread, it will never
140 receive events and all socket operations will time out.
141 BTW, the main thread must not be stopped using sleep or block
142 on a semaphore (a bad idea in any case) or socket operations
145 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
146 the main thread. Because secondary threads do not have run loops,
147 adding event notifications to the "Current" loop would have no
148 effect at all, events would never fire.
150 wxASSERT_MSG( wxIsMainThread(),
151 "sockets must be initialized from the main thread" );
153 wxAppConsole
* const app
= wxAppConsole::GetInstance();
154 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
156 ms_manager
= app
->GetTraits()->GetSocketManager();
159 // ==========================================================================
161 // ==========================================================================
163 wxSocketImpl::wxSocketImpl(wxSocketBase
& wxsocket
)
164 : m_wxsocket(&wxsocket
)
166 m_fd
= INVALID_SOCKET
;
170 m_error
= wxSOCKET_NOERROR
;
173 m_non_blocking
= false;
175 SetTimeout(wxsocket
.GetTimeout() * 1000);
177 m_establishing
= false;
181 m_initialRecvBufferSize
= -1;
182 m_initialSendBufferSize
= -1;
185 wxSocketImpl::~wxSocketImpl()
187 if (m_fd
!= INVALID_SOCKET
)
191 GAddress_destroy(m_local
);
194 GAddress_destroy(m_peer
);
197 bool wxSocketImpl::PreCreateCheck(GAddress
*addr
)
199 if ( m_fd
!= INVALID_SOCKET
)
201 m_error
= wxSOCKET_INVSOCK
;
205 if ( !addr
|| !addr
->m_addr
)
207 m_error
= wxSOCKET_INVADDR
;
214 void wxSocketImpl::PostCreation()
216 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
218 EnableSocketOption(SO_NOSIGPIPE
);
222 EnableSocketOption(SO_REUSEADDR
);
226 wxASSERT_MSG( !m_stream
, "broadcasting is for datagram sockets only" );
228 EnableSocketOption(SO_BROADCAST
);
231 if ( m_initialRecvBufferSize
>= 0 )
232 SetSocketOption(SO_RCVBUF
, m_initialRecvBufferSize
);
233 if ( m_initialSendBufferSize
>= 0 )
234 SetSocketOption(SO_SNDBUF
, m_initialSendBufferSize
);
236 // FIXME: shouldn't we check for m_non_blocking here? as it is now, all our
237 // sockets are non-blocking
238 UnblockAndRegisterWithEventLoop();
241 wxSocketError
wxSocketImpl::UpdateLocalAddress()
243 WX_SOCKLEN_T lenAddr
;
244 if ( getsockname(m_fd
, m_local
->m_addr
, &lenAddr
) != 0 )
247 m_error
= wxSOCKET_IOERR
;
251 m_local
->m_len
= lenAddr
;
253 return wxSOCKET_NOERROR
;
256 wxSocketError
wxSocketImpl::CreateServer()
258 if ( !PreCreateCheck(m_local
) )
264 // do create the socket
265 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
267 if ( m_fd
== INVALID_SOCKET
)
269 m_error
= wxSOCKET_IOERR
;
270 return wxSOCKET_IOERR
;
275 // and then bind to and listen on it
277 // FIXME: should we test for m_dobind here?
278 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
279 m_error
= wxSOCKET_IOERR
;
283 if ( listen(m_fd
, 5) != 0 )
284 m_error
= wxSOCKET_IOERR
;
293 // finally retrieve the address we effectively bound to
294 return UpdateLocalAddress();
297 wxSocketError
wxSocketImpl::CreateClient()
299 if ( !PreCreateCheck(m_peer
) )
302 m_fd
= socket(m_peer
->m_realfamily
, SOCK_STREAM
, 0);
304 if ( m_fd
== INVALID_SOCKET
)
306 m_error
= wxSOCKET_IOERR
;
307 return wxSOCKET_IOERR
;
312 // If a local address has been set, then bind to it before calling connect
313 if ( m_local
&& m_local
->m_addr
)
315 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
318 m_error
= wxSOCKET_IOERR
;
323 // Connect to the peer and handle the EWOULDBLOCK return value in
324 // platform-specific code
325 return DoHandleConnect(connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
));
329 wxSocketError
wxSocketImpl::CreateUDP()
331 if ( !PreCreateCheck(m_local
) )
337 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
339 if ( m_fd
== INVALID_SOCKET
)
341 m_error
= wxSOCKET_IOERR
;
342 return wxSOCKET_IOERR
;
349 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
352 m_error
= wxSOCKET_IOERR
;
356 return UpdateLocalAddress();
359 return wxSOCKET_NOERROR
;
363 void wxSocketImpl::Close()
365 if ( m_fd
!= INVALID_SOCKET
)
368 m_fd
= INVALID_SOCKET
;
373 * Disallow further read/write operations on this socket, close
374 * the fd and disable all callbacks.
376 void wxSocketImpl::Shutdown()
378 if ( m_fd
!= INVALID_SOCKET
)
380 shutdown(m_fd
, 1 /* SD_SEND */);
384 m_detected
= wxSOCKET_LOST_FLAG
;
388 * Sets the timeout for blocking calls. Time is expressed in
391 void wxSocketImpl::SetTimeout(unsigned long millis
)
393 m_timeout
.tv_sec
= (millis
/ 1000);
394 m_timeout
.tv_usec
= (millis
% 1000) * 1000;
397 void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event
)
399 m_wxsocket
->OnRequest(event
);
402 /* Address handling */
405 * Set or get the local or peer address for this socket. The 'set'
406 * functions return wxSOCKET_NOERROR on success, an error code otherwise.
407 * The 'get' functions return a pointer to a GAddress object on success,
408 * or NULL otherwise, in which case they set the error code of the
409 * corresponding socket.
412 * wxSOCKET_INVSOCK - the socket is not valid.
413 * wxSOCKET_INVADDR - the address is not valid.
415 wxSocketError
wxSocketImpl::SetLocal(GAddress
*address
)
417 /* the socket must be initialized, or it must be a server */
418 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
420 m_error
= wxSOCKET_INVSOCK
;
421 return wxSOCKET_INVSOCK
;
425 if (address
== NULL
|| address
->m_family
== wxSOCKET_NOFAMILY
)
427 m_error
= wxSOCKET_INVADDR
;
428 return wxSOCKET_INVADDR
;
432 GAddress_destroy(m_local
);
434 m_local
= GAddress_copy(address
);
436 return wxSOCKET_NOERROR
;
439 wxSocketError
wxSocketImpl::SetPeer(GAddress
*address
)
442 if (address
== NULL
|| address
->m_family
== wxSOCKET_NOFAMILY
)
444 m_error
= wxSOCKET_INVADDR
;
445 return wxSOCKET_INVADDR
;
449 GAddress_destroy(m_peer
);
451 m_peer
= GAddress_copy(address
);
453 return wxSOCKET_NOERROR
;
456 GAddress
*wxSocketImpl::GetLocal()
460 WX_SOCKLEN_T size
= sizeof(addr
);
463 /* try to get it from the m_local var first */
465 return GAddress_copy(m_local
);
467 /* else, if the socket is initialized, try getsockname */
468 if (m_fd
== INVALID_SOCKET
)
470 m_error
= wxSOCKET_INVSOCK
;
474 if (getsockname(m_fd
, (sockaddr
*)&addr
, &size
) == SOCKET_ERROR
)
476 m_error
= wxSOCKET_IOERR
;
480 /* got a valid address from getsockname, create a GAddress object */
481 if ((address
= GAddress_new()) == NULL
)
483 m_error
= wxSOCKET_MEMERR
;
487 if ((err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
)) != wxSOCKET_NOERROR
)
489 GAddress_destroy(address
);
497 GAddress
*wxSocketImpl::GetPeer()
499 /* try to get it from the m_peer var */
501 return GAddress_copy(m_peer
);
506 bool wxSocketImpl::DoBlockWithTimeout(wxSocketEventFlags flags
)
508 if ( !m_non_blocking
)
512 wxFD_SET(m_fd
, &fds
);
515 *readfds
= flags
& wxSOCKET_INPUT_FLAG
? &fds
: NULL
,
516 *writefds
= flags
& wxSOCKET_OUTPUT_FLAG
? &fds
: NULL
;
518 // make a copy as it can be modified by select()
519 struct timeval tv
= m_timeout
;
520 int ret
= select(m_fd
+ 1, readfds
, writefds
, NULL
, &tv
);
525 m_error
= wxSOCKET_TIMEDOUT
;
529 m_error
= wxSOCKET_IOERR
;
533 //else: we're non-blocking, never block
538 // ==========================================================================
540 // ==========================================================================
542 // --------------------------------------------------------------------------
543 // Initialization and shutdown
544 // --------------------------------------------------------------------------
546 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
547 // to m_countInit with a crit section
548 size_t wxSocketBase::m_countInit
= 0;
550 bool wxSocketBase::IsInitialized()
552 return m_countInit
> 0;
555 bool wxSocketBase::Initialize()
557 if ( !m_countInit
++ )
559 wxSocketManager
* const manager
= wxSocketManager::Get();
560 if ( !manager
|| !manager
->OnInit() )
571 void wxSocketBase::Shutdown()
573 // we should be initialized
574 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
575 if ( --m_countInit
== 0 )
577 wxSocketManager
* const manager
= wxSocketManager::Get();
578 wxCHECK_RET( manager
, "should have a socket manager" );
584 // --------------------------------------------------------------------------
586 // --------------------------------------------------------------------------
588 void wxSocketBase::Init()
591 m_type
= wxSOCKET_UNINIT
;
603 m_beingDeleted
= false;
617 if ( !IsInitialized() )
619 // this Initialize() will be undone by wxSocketModule::OnExit(), all
620 // the other calls to it should be matched by a call to Shutdown()
625 wxSocketBase::wxSocketBase()
630 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
639 wxSocketBase::~wxSocketBase()
641 // Just in case the app called Destroy() *and* then deleted the socket
642 // immediately: don't leave dangling pointers.
643 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
645 traits
->RemoveFromPendingDelete(this);
647 // Shutdown and close the socket
651 // Destroy the implementation object
654 // Free the pushback buffer
659 bool wxSocketBase::Destroy()
661 // Delayed destruction: the socket will be deleted during the next idle
662 // loop iteration. This ensures that all pending events have been
664 m_beingDeleted
= true;
666 // Shutdown and close the socket
669 // Supress events from now on
672 // schedule this object for deletion
673 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
676 // let the traits object decide what to do with us
677 traits
->ScheduleForDestroy(this);
679 else // no app or no traits
681 // in wxBase we might have no app object at all, don't leak memory
688 // ----------------------------------------------------------------------------
690 // ----------------------------------------------------------------------------
692 wxSocketError
wxSocketBase::LastError() const
694 return m_impl
->GetError();
697 // --------------------------------------------------------------------------
699 // --------------------------------------------------------------------------
701 // The following IO operations update m_error and m_lcount:
702 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
704 // TODO: Should Connect, Accept and AcceptWith update m_error?
706 bool wxSocketBase::Close()
708 // Interrupt pending waits
715 m_establishing
= false;
719 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
724 m_lcount
= DoRead(buffer
, nbytes
);
726 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
727 if (m_flags
& wxSOCKET_WAITALL
)
728 m_error
= (m_lcount
!= nbytes
);
730 m_error
= (m_lcount
== 0);
732 // Allow read events from now on
738 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
740 // We use pointer arithmetic here which doesn't work with void pointers.
741 char *buffer
= static_cast<char *>(buffer_
);
743 // Try the push back buffer first, even before checking whether the socket
744 // is valid to allow reading previously pushed back data from an already
746 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
750 // If it's indeed closed or if read everything, there is nothing more to do.
751 if ( !m_impl
|| !nbytes
)
754 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
757 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
758 // polling the socket and don't block at all.
759 if ( m_flags
& wxSOCKET_NOWAIT
)
761 wxSocketUnblocker
unblock(m_impl
);
762 int ret
= m_impl
->Read(buffer
, nbytes
);
768 else // blocking socket
772 // Wait until socket becomes ready for reading dispatching the GUI
773 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
774 // specified to disable this.
775 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
778 const int ret
= m_impl
->Read(buffer
, nbytes
);
781 // for connection-oriented (e.g. TCP) sockets we can only read
782 // 0 bytes if the other end has been closed, and for
783 // connectionless ones (UDP) this flag doesn't make sense
784 // anyhow so we can set it to true too without doing any harm
791 // this will be always interpreted as error by Read()
797 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
798 // something and we don't need to wait for all nbytes bytes to be
800 if ( !(m_flags
& wxSOCKET_WAITALL
) )
803 // Otherwise continue reading until we do read everything.
815 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
817 wxUint32 len
, len2
, sig
, total
;
822 unsigned char sig
[4];
823 unsigned char len
[4];
832 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
834 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
837 sig
= (wxUint32
)msg
.sig
[0];
838 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
839 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
840 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
842 if (sig
!= 0xfeeddead)
844 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
848 len
= (wxUint32
)msg
.len
[0];
849 len
|= (wxUint32
)(msg
.len
[1] << 8);
850 len
|= (wxUint32
)(msg
.len
[2] << 16);
851 len
|= (wxUint32
)(msg
.len
[3] << 24);
861 // Don't attempt to read if the msg was zero bytes long.
864 total
= DoRead(buffer
, len
);
872 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
875 // NOTE: discarded bytes don't add to m_lcount.
878 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
879 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
880 len2
-= (wxUint32
)discard_len
;
882 while ((discard_len
> 0) && len2
);
884 delete [] discard_buffer
;
889 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
892 sig
= (wxUint32
)msg
.sig
[0];
893 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
894 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
895 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
897 if (sig
!= 0xdeadfeed)
899 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
915 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
920 m_lcount
= DoRead(buffer
, nbytes
);
921 Pushback(buffer
, m_lcount
);
923 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
924 if (m_flags
& wxSOCKET_WAITALL
)
925 m_error
= (m_lcount
!= nbytes
);
927 m_error
= (m_lcount
== 0);
929 // Allow read events again
935 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
940 m_lcount
= DoWrite(buffer
, nbytes
);
942 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
943 if (m_flags
& wxSOCKET_WAITALL
)
944 m_error
= (m_lcount
!= nbytes
);
946 m_error
= (m_lcount
== 0);
948 // Allow write events again
954 // This function is a mirror image of DoRead() except that it doesn't use the
955 // push back buffer, please see comments there
956 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
958 const char *buffer
= static_cast<const char *>(buffer_
);
960 // Return if there is nothing to read or the socket is (already?) closed.
961 if ( !m_impl
|| !nbytes
)
964 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
967 if ( m_flags
& wxSOCKET_NOWAIT
)
969 wxSocketUnblocker
unblock(m_impl
);
970 const int ret
= m_impl
->Write(buffer
, nbytes
);
974 else // blocking socket
978 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
981 const int ret
= m_impl
->Write(buffer
, nbytes
);
992 if ( !(m_flags
& wxSOCKET_WAITALL
) )
1006 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
1012 unsigned char sig
[4];
1013 unsigned char len
[4];
1016 // Mask write events
1021 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
1023 msg
.sig
[0] = (unsigned char) 0xad;
1024 msg
.sig
[1] = (unsigned char) 0xde;
1025 msg
.sig
[2] = (unsigned char) 0xed;
1026 msg
.sig
[3] = (unsigned char) 0xfe;
1028 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
1029 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
1030 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
1031 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
1033 if (DoWrite(&msg
, sizeof(msg
)) < sizeof(msg
))
1036 total
= DoWrite(buffer
, nbytes
);
1041 msg
.sig
[0] = (unsigned char) 0xed;
1042 msg
.sig
[1] = (unsigned char) 0xfe;
1043 msg
.sig
[2] = (unsigned char) 0xad;
1044 msg
.sig
[3] = (unsigned char) 0xde;
1048 msg
.len
[3] = (char) 0;
1050 if ((DoWrite(&msg
, sizeof(msg
))) < sizeof(msg
))
1053 // everything was OK
1064 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
1067 Pushback(buffer
, nbytes
);
1075 wxSocketBase
& wxSocketBase::Discard()
1077 char *buffer
= new char[MAX_DISCARD_SIZE
];
1084 SetFlags(wxSOCKET_NOWAIT
);
1088 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
1091 while (ret
== MAX_DISCARD_SIZE
);
1097 // Allow read events again
1103 // --------------------------------------------------------------------------
1105 // --------------------------------------------------------------------------
1108 * Polls the socket to determine its status. This function will
1109 * check for the events specified in the 'flags' parameter, and
1110 * it will return a mask indicating which operations can be
1111 * performed. This function won't block, regardless of the
1112 * mode (blocking | nonblocking) of the socket.
1114 wxSocketEventFlags
wxSocketImpl::Select(wxSocketEventFlags flags
)
1118 wxSocketEventFlags result
= 0;
1124 if (m_fd
== INVALID_SOCKET
)
1125 return (wxSOCKET_LOST_FLAG
& flags
);
1127 /* Do not use a static struct, Linux can garble it */
1131 wxFD_ZERO(&readfds
);
1132 wxFD_ZERO(&writefds
);
1133 wxFD_ZERO(&exceptfds
);
1134 wxFD_SET(m_fd
, &readfds
);
1135 if (flags
& wxSOCKET_OUTPUT_FLAG
|| flags
& wxSOCKET_CONNECTION_FLAG
)
1136 wxFD_SET(m_fd
, &writefds
);
1137 wxFD_SET(m_fd
, &exceptfds
);
1139 /* Check 'sticky' CONNECTION flag first */
1140 result
|= wxSOCKET_CONNECTION_FLAG
& m_detected
;
1142 /* If we have already detected a LOST event, then don't try
1143 * to do any further processing.
1145 if ((m_detected
& wxSOCKET_LOST_FLAG
) != 0)
1147 m_establishing
= false;
1148 return (wxSOCKET_LOST_FLAG
& flags
);
1151 /* Try select now */
1152 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
1154 /* What to do here? */
1155 return (result
& flags
);
1158 /* Check for exceptions and errors */
1159 if (wxFD_ISSET(m_fd
, &exceptfds
))
1161 m_establishing
= false;
1162 m_detected
= wxSOCKET_LOST_FLAG
;
1164 /* LOST event: Abort any further processing */
1165 return (wxSOCKET_LOST_FLAG
& flags
);
1168 /* Check for readability */
1169 if (wxFD_ISSET(m_fd
, &readfds
))
1171 result
|= wxSOCKET_INPUT_FLAG
;
1173 if (m_server
&& m_stream
)
1175 /* This is a TCP server socket that detected a connection.
1176 While the INPUT_FLAG is also set, it doesn't matter on
1177 this kind of sockets, as we can only Accept() from them. */
1178 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1182 /* Check for writability */
1183 if (wxFD_ISSET(m_fd
, &writefds
))
1185 if (m_establishing
&& !m_server
)
1188 SOCKOPTLEN_T len
= sizeof(error
);
1189 m_establishing
= false;
1190 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1194 m_detected
= wxSOCKET_LOST_FLAG
;
1196 /* LOST event: Abort any further processing */
1197 return (wxSOCKET_LOST_FLAG
& flags
);
1201 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1206 result
|= wxSOCKET_OUTPUT_FLAG
;
1210 return (result
| m_detected
) & flags
;
1213 // All Wait functions poll the socket using Select() to
1214 // check for the specified combination of conditions, until one
1215 // of these conditions become true, an error occurs, or the
1216 // timeout elapses. The polling loop runs the event loop so that
1217 // this won't block the GUI.
1220 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1222 wxCHECK_MSG( m_impl
, false, "can't wait on invalid socket" );
1224 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1225 m_interrupt
= false;
1228 // Use either the provided timeout or the default timeout value associated
1229 // with this socket.
1231 // TODO: allow waiting forever, see #9443
1232 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1233 : seconds
* 1000 + milliseconds
;
1234 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1236 // Get the active event loop which we'll use for the message dispatching
1237 // when running in the main thread
1238 wxEventLoopBase
*eventLoop
;
1239 if ( wxIsMainThread() )
1241 eventLoop
= wxEventLoop::GetActive();
1243 else // in worker thread
1245 // We never dispatch messages from threads other than the main one.
1249 // Wait in an active polling loop: notice that the loop is executed at
1250 // least once, even if timeout is 0 (i.e. polling).
1251 bool gotEvent
= false;
1254 // We always stop waiting when the connection is lost as it doesn't
1255 // make sense to continue further, even if wxSOCKET_LOST_FLAG is not
1256 // specified in flags to wait for.
1257 const wxSocketEventFlags
1258 result
= m_impl
->Select(flags
| wxSOCKET_LOST_FLAG
);
1260 // Incoming connection (server) or connection established (client)?
1261 if ( result
& wxSOCKET_CONNECTION_FLAG
)
1264 m_establishing
= false;
1269 // Data available or output buffer ready?
1270 if ( (result
& wxSOCKET_INPUT_FLAG
) || (result
& wxSOCKET_OUTPUT_FLAG
) )
1277 if ( result
& wxSOCKET_LOST_FLAG
)
1279 m_connected
= false;
1280 m_establishing
= false;
1281 if ( flags
& wxSOCKET_LOST_FLAG
)
1290 const wxMilliClock_t timeNow
= wxGetLocalTimeMillis();
1291 if ( timeNow
>= timeEnd
)
1296 // This function is only called if wxSOCKET_BLOCK flag was not used
1297 // and so we should dispatch the events if there is an event loop
1298 // capable of doing it.
1299 if ( eventLoop
->Pending() )
1300 eventLoop
->Dispatch();
1303 else // no event loop or waiting in another thread
1305 // We're busy waiting but at least give up the rest of our current
1309 #endif // wxUSE_THREADS
1315 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1317 return DoWait(seconds
, milliseconds
,
1318 wxSOCKET_INPUT_FLAG
|
1319 wxSOCKET_OUTPUT_FLAG
|
1320 wxSOCKET_CONNECTION_FLAG
|
1325 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1327 // Check pushback buffer before entering DoWait
1331 // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
1332 // because of the semantics of WaitForRead: a return value of true means
1333 // that a Read call will return immediately, not that there is
1334 // actually data to read.
1335 return DoWait(seconds
, milliseconds
, wxSOCKET_INPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1339 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1341 return DoWait(seconds
, milliseconds
, wxSOCKET_OUTPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1344 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1346 return DoWait(seconds
, milliseconds
, wxSOCKET_LOST_FLAG
);
1349 // --------------------------------------------------------------------------
1351 // --------------------------------------------------------------------------
1354 // Get local or peer address
1357 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
1364 peer
= m_impl
->GetPeer();
1366 // copying a null address would just trigger an assert anyway
1371 addr_man
.SetAddress(peer
);
1372 GAddress_destroy(peer
);
1377 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1384 local
= m_impl
->GetLocal();
1385 addr_man
.SetAddress(local
);
1386 GAddress_destroy(local
);
1392 // Save and restore socket state
1395 void wxSocketBase::SaveState()
1397 wxSocketState
*state
;
1399 state
= new wxSocketState();
1401 state
->m_flags
= m_flags
;
1402 state
->m_notify
= m_notify
;
1403 state
->m_eventmask
= m_eventmask
;
1404 state
->m_clientData
= m_clientData
;
1406 m_states
.Append(state
);
1409 void wxSocketBase::RestoreState()
1411 wxList::compatibility_iterator node
;
1412 wxSocketState
*state
;
1414 node
= m_states
.GetLast();
1418 state
= (wxSocketState
*)node
->GetData();
1420 m_flags
= state
->m_flags
;
1421 m_notify
= state
->m_notify
;
1422 m_eventmask
= state
->m_eventmask
;
1423 m_clientData
= state
->m_clientData
;
1425 m_states
.Erase(node
);
1430 // Timeout and flags
1433 void wxSocketBase::SetTimeout(long seconds
)
1435 m_timeout
= seconds
;
1438 m_impl
->SetTimeout(m_timeout
* 1000);
1441 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1443 // Do some sanity checking on the flags used: not all values can be used
1445 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1446 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1447 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1448 "wxSOCKET_NOWAIT doesn't make sense" );
1454 // --------------------------------------------------------------------------
1456 // --------------------------------------------------------------------------
1458 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1460 switch(notification
)
1462 case wxSOCKET_CONNECTION
:
1463 m_establishing
= false;
1467 // If we are in the middle of a R/W operation, do not
1468 // propagate events to users. Also, filter 'late' events
1469 // which are no longer valid.
1471 case wxSOCKET_INPUT
:
1472 if (m_reading
|| !m_impl
->Select(wxSOCKET_INPUT_FLAG
))
1476 case wxSOCKET_OUTPUT
:
1477 if (m_writing
|| !m_impl
->Select(wxSOCKET_OUTPUT_FLAG
))
1482 m_connected
= false;
1483 m_establishing
= false;
1486 case wxSOCKET_MAX_EVENT
:
1487 wxFAIL_MSG( "unexpected notification" );
1491 // Schedule the event
1493 wxSocketEventFlags flag
= 0;
1495 switch (notification
)
1497 case wxSOCKET_INPUT
: flag
= wxSOCKET_INPUT_FLAG
; break;
1498 case wxSOCKET_OUTPUT
: flag
= wxSOCKET_OUTPUT_FLAG
; break;
1499 case wxSOCKET_CONNECTION
: flag
= wxSOCKET_CONNECTION_FLAG
; break;
1500 case wxSOCKET_LOST
: flag
= wxSOCKET_LOST_FLAG
; break;
1502 wxLogWarning(_("wxSocket: unknown event!."));
1506 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1510 wxSocketEvent
event(m_id
);
1511 event
.m_event
= notification
;
1512 event
.m_clientData
= m_clientData
;
1513 event
.SetEventObject(this);
1515 m_handler
->AddPendingEvent(event
);
1520 void wxSocketBase::Notify(bool notify
)
1524 m_impl
->Notify(notify
);
1527 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1529 m_eventmask
= flags
;
1532 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1534 m_handler
= &handler
;
1538 // --------------------------------------------------------------------------
1540 // --------------------------------------------------------------------------
1542 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1546 if (m_unread
== NULL
)
1547 m_unread
= malloc(size
);
1552 tmp
= malloc(m_unrd_size
+ size
);
1553 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1559 m_unrd_size
+= size
;
1561 memcpy(m_unread
, buffer
, size
);
1564 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1566 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1571 if (size
> (m_unrd_size
-m_unrd_cur
))
1572 size
= m_unrd_size
-m_unrd_cur
;
1574 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1579 if (m_unrd_size
== m_unrd_cur
)
1592 // ==========================================================================
1594 // ==========================================================================
1596 // --------------------------------------------------------------------------
1598 // --------------------------------------------------------------------------
1600 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1601 wxSocketFlags flags
)
1602 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1604 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1606 m_impl
= wxSocketImpl::Create(*this);
1610 wxLogTrace( wxTRACE_Socket
, _T("*** Failed to create m_impl") );
1614 // Setup the socket as server
1615 m_impl
->Notify(m_notify
);
1616 m_impl
->SetLocal(addr_man
.GetAddress());
1618 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1619 m_impl
->SetReusable();
1621 if (GetFlags() & wxSOCKET_BROADCAST
) {
1622 m_impl
->SetBroadcast();
1624 if (GetFlags() & wxSOCKET_NOBIND
) {
1625 m_impl
->DontDoBind();
1628 if (m_impl
->CreateServer() != wxSOCKET_NOERROR
)
1633 wxLogTrace( wxTRACE_Socket
, _T("*** CreateServer() failed") );
1637 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_impl
->m_fd
);
1640 // --------------------------------------------------------------------------
1642 // --------------------------------------------------------------------------
1644 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1649 // If wait == false, then the call should be nonblocking.
1650 // When we are finished, we put the socket to blocking mode
1652 wxSocketUnblocker
unblock(m_impl
, !wait
);
1653 sock
.m_impl
= m_impl
->WaitConnection(sock
);
1658 sock
.m_type
= wxSOCKET_BASE
;
1659 sock
.m_connected
= true;
1664 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1666 wxSocketBase
* sock
= new wxSocketBase();
1668 sock
->SetFlags(m_flags
);
1670 if (!AcceptWith(*sock
, wait
))
1679 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1681 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
);
1684 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1686 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1688 SOCKOPTLEN_T lenreal
;
1689 if ( getsockopt(m_impl
->m_fd
, level
, optname
,
1690 static_cast<char *>(optval
), &lenreal
) != 0 )
1699 wxSocketBase::SetOption(int level
, int optname
, const void *optval
, int optlen
)
1701 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1703 return setsockopt(m_impl
->m_fd
, level
, optname
,
1704 static_cast<const char *>(optval
), optlen
) == 0;
1707 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1709 GAddress
* la
= local
.GetAddress();
1711 // If the address is valid, save it for use when we call Connect
1712 if (la
&& la
->m_addr
)
1714 m_localAddress
= local
;
1722 // ==========================================================================
1724 // ==========================================================================
1726 // --------------------------------------------------------------------------
1728 // --------------------------------------------------------------------------
1730 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1731 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1733 m_initialRecvBufferSize
=
1734 m_initialSendBufferSize
= -1;
1737 wxSocketClient::~wxSocketClient()
1741 // --------------------------------------------------------------------------
1743 // --------------------------------------------------------------------------
1745 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1746 const wxSockAddress
* local
,
1751 // Shutdown and destroy the socket
1756 m_impl
= wxSocketImpl::Create(*this);
1757 m_connected
= false;
1758 m_establishing
= false;
1763 // If wait == false, then the call should be nonblocking. When we are
1764 // finished, we put the socket to blocking mode again.
1765 wxSocketUnblocker
unblock(m_impl
, !wait
);
1767 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1768 if (GetFlags() & wxSOCKET_REUSEADDR
)
1770 m_impl
->SetReusable();
1772 if (GetFlags() & wxSOCKET_BROADCAST
)
1774 m_impl
->SetBroadcast();
1776 if (GetFlags() & wxSOCKET_NOBIND
)
1778 m_impl
->DontDoBind();
1781 // If no local address was passed and one has been set, use the one that was Set
1782 if (!local
&& m_localAddress
.GetAddress())
1784 local
= &m_localAddress
;
1787 // Bind to the local IP address and port, when provided
1790 GAddress
* la
= local
->GetAddress();
1792 if (la
&& la
->m_addr
)
1793 m_impl
->SetLocal(la
);
1796 m_impl
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1798 m_impl
->SetPeer(addr_man
.GetAddress());
1799 const wxSocketError err
= m_impl
->CreateClient();
1801 //this will register for callbacks - must be called after m_impl->m_fd was initialized
1802 m_impl
->Notify(m_notify
);
1804 if (err
!= wxSOCKET_NOERROR
)
1806 if (err
== wxSOCKET_WOULDBLOCK
)
1807 m_establishing
= true;
1816 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1818 return DoConnect(addr_man
, NULL
, wait
);
1821 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1822 const wxSockAddress
& local
,
1825 return DoConnect(addr_man
, &local
, wait
);
1828 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1832 // this happens if the initial attempt to connect succeeded without
1837 wxCHECK_MSG( m_establishing
&& m_impl
, false,
1838 "No connection establishment attempt in progress" );
1840 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1841 // true if the connection establishment process is finished, whether it is
1842 // over because we successfully connected or because we were not able to
1844 return DoWait(seconds
, milliseconds
,
1845 wxSOCKET_CONNECTION_FLAG
| wxSOCKET_LOST_FLAG
);
1848 // ==========================================================================
1850 // ==========================================================================
1852 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1853 wxSocketFlags flags
)
1854 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1856 // Create the socket
1857 m_impl
= wxSocketImpl::Create(*this);
1862 m_impl
->Notify(m_notify
);
1863 // Setup the socket as non connection oriented
1864 m_impl
->SetLocal(addr
.GetAddress());
1865 if (flags
& wxSOCKET_REUSEADDR
)
1867 m_impl
->SetReusable();
1869 if (GetFlags() & wxSOCKET_BROADCAST
)
1871 m_impl
->SetBroadcast();
1873 if (GetFlags() & wxSOCKET_NOBIND
)
1875 m_impl
->DontDoBind();
1878 if ( m_impl
->CreateUDP() != wxSOCKET_NOERROR
)
1885 // Initialize all stuff
1886 m_connected
= false;
1887 m_establishing
= false;
1890 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1899 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1903 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1905 m_impl
->SetPeer(addr
.GetAddress());
1910 // ==========================================================================
1912 // ==========================================================================
1914 class wxSocketModule
: public wxModule
1917 virtual bool OnInit()
1919 // wxSocketBase will call Initialize() itself only if sockets are
1920 // really used, don't do it from here
1924 virtual void OnExit()
1926 if ( wxSocketBase::IsInitialized() )
1927 wxSocketBase::Shutdown();
1931 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1934 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1936 #endif // wxUSE_SOCKETS