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;
618 if ( !IsInitialized() )
620 // this Initialize() will be undone by wxSocketModule::OnExit(), all
621 // the other calls to it should be matched by a call to Shutdown()
626 wxSocketBase::wxSocketBase()
631 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
640 wxSocketBase::~wxSocketBase()
642 // Just in case the app called Destroy() *and* then deleted the socket
643 // immediately: don't leave dangling pointers.
644 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
646 traits
->RemoveFromPendingDelete(this);
648 // Shutdown and close the socket
652 // Destroy the implementation object
655 // Free the pushback buffer
660 bool wxSocketBase::Destroy()
662 // Delayed destruction: the socket will be deleted during the next idle
663 // loop iteration. This ensures that all pending events have been
665 m_beingDeleted
= true;
667 // Shutdown and close the socket
670 // Supress events from now on
673 // schedule this object for deletion
674 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
677 // let the traits object decide what to do with us
678 traits
->ScheduleForDestroy(this);
680 else // no app or no traits
682 // in wxBase we might have no app object at all, don't leak memory
689 // ----------------------------------------------------------------------------
691 // ----------------------------------------------------------------------------
693 wxSocketError
wxSocketBase::LastError() const
695 return m_impl
->GetError();
698 // --------------------------------------------------------------------------
700 // --------------------------------------------------------------------------
702 // The following IO operations update m_error and m_lcount:
703 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
705 // TODO: Should Connect, Accept and AcceptWith update m_error?
707 bool wxSocketBase::Close()
709 // Interrupt pending waits
716 m_establishing
= false;
720 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
725 m_lcount
= DoRead(buffer
, nbytes
);
727 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
728 if (m_flags
& wxSOCKET_WAITALL
)
729 m_error
= (m_lcount
!= nbytes
);
731 m_error
= (m_lcount
== 0);
733 // Allow read events from now on
739 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
741 // We use pointer arithmetic here which doesn't work with void pointers.
742 char *buffer
= static_cast<char *>(buffer_
);
744 // Try the push back buffer first, even before checking whether the socket
745 // is valid to allow reading previously pushed back data from an already
747 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
751 // If it's indeed closed or if read everything, there is nothing more to do.
752 if ( !m_impl
|| !nbytes
)
755 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
758 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
759 // polling the socket and don't block at all.
760 if ( m_flags
& wxSOCKET_NOWAIT
)
762 wxSocketUnblocker
unblock(m_impl
);
763 int ret
= m_impl
->Read(buffer
, nbytes
);
769 else // blocking socket
773 // Wait until socket becomes ready for reading dispatching the GUI
774 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
775 // specified to disable this.
776 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
779 const int ret
= m_impl
->Read(buffer
, nbytes
);
782 // for connection-oriented (e.g. TCP) sockets we can only read
783 // 0 bytes if the other end has been closed, and for
784 // connectionless ones (UDP) this flag doesn't make sense
785 // anyhow so we can set it to true too without doing any harm
792 // this will be always interpreted as error by Read()
798 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
799 // something and we don't need to wait for all nbytes bytes to be
801 if ( !(m_flags
& wxSOCKET_WAITALL
) )
804 // Otherwise continue reading until we do read everything.
816 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
818 wxUint32 len
, len2
, sig
, total
;
823 unsigned char sig
[4];
824 unsigned char len
[4];
833 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
835 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
838 sig
= (wxUint32
)msg
.sig
[0];
839 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
840 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
841 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
843 if (sig
!= 0xfeeddead)
845 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
849 len
= (wxUint32
)msg
.len
[0];
850 len
|= (wxUint32
)(msg
.len
[1] << 8);
851 len
|= (wxUint32
)(msg
.len
[2] << 16);
852 len
|= (wxUint32
)(msg
.len
[3] << 24);
862 // Don't attempt to read if the msg was zero bytes long.
865 total
= DoRead(buffer
, len
);
873 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
876 // NOTE: discarded bytes don't add to m_lcount.
879 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
880 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
881 len2
-= (wxUint32
)discard_len
;
883 while ((discard_len
> 0) && len2
);
885 delete [] discard_buffer
;
890 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
893 sig
= (wxUint32
)msg
.sig
[0];
894 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
895 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
896 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
898 if (sig
!= 0xdeadfeed)
900 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
916 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
921 m_lcount
= DoRead(buffer
, nbytes
);
922 Pushback(buffer
, m_lcount
);
924 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
925 if (m_flags
& wxSOCKET_WAITALL
)
926 m_error
= (m_lcount
!= nbytes
);
928 m_error
= (m_lcount
== 0);
930 // Allow read events again
936 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
941 m_lcount
= DoWrite(buffer
, nbytes
);
943 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
944 if (m_flags
& wxSOCKET_WAITALL
)
945 m_error
= (m_lcount
!= nbytes
);
947 m_error
= (m_lcount
== 0);
949 // Allow write events again
955 // This function is a mirror image of DoRead() except that it doesn't use the
956 // push back buffer, please see comments there
957 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
959 const char *buffer
= static_cast<const char *>(buffer_
);
961 // Return if there is nothing to read or the socket is (already?) closed.
962 if ( !m_impl
|| !nbytes
)
965 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
968 if ( m_flags
& wxSOCKET_NOWAIT
)
970 wxSocketUnblocker
unblock(m_impl
);
971 const int ret
= m_impl
->Write(buffer
, nbytes
);
975 else // blocking socket
979 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
982 const int ret
= m_impl
->Write(buffer
, nbytes
);
993 if ( !(m_flags
& wxSOCKET_WAITALL
) )
1007 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
1013 unsigned char sig
[4];
1014 unsigned char len
[4];
1017 // Mask write events
1022 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
1024 msg
.sig
[0] = (unsigned char) 0xad;
1025 msg
.sig
[1] = (unsigned char) 0xde;
1026 msg
.sig
[2] = (unsigned char) 0xed;
1027 msg
.sig
[3] = (unsigned char) 0xfe;
1029 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
1030 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
1031 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
1032 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
1034 if (DoWrite(&msg
, sizeof(msg
)) < sizeof(msg
))
1037 total
= DoWrite(buffer
, nbytes
);
1042 msg
.sig
[0] = (unsigned char) 0xed;
1043 msg
.sig
[1] = (unsigned char) 0xfe;
1044 msg
.sig
[2] = (unsigned char) 0xad;
1045 msg
.sig
[3] = (unsigned char) 0xde;
1049 msg
.len
[3] = (char) 0;
1051 if ((DoWrite(&msg
, sizeof(msg
))) < sizeof(msg
))
1054 // everything was OK
1065 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
1068 Pushback(buffer
, nbytes
);
1076 wxSocketBase
& wxSocketBase::Discard()
1078 char *buffer
= new char[MAX_DISCARD_SIZE
];
1085 SetFlags(wxSOCKET_NOWAIT
);
1089 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
1092 while (ret
== MAX_DISCARD_SIZE
);
1098 // Allow read events again
1104 // --------------------------------------------------------------------------
1106 // --------------------------------------------------------------------------
1109 * Polls the socket to determine its status. This function will
1110 * check for the events specified in the 'flags' parameter, and
1111 * it will return a mask indicating which operations can be
1112 * performed. This function won't block, regardless of the
1113 * mode (blocking | nonblocking) of the socket.
1115 wxSocketEventFlags
wxSocketImpl::Select(wxSocketEventFlags flags
)
1119 wxSocketEventFlags result
= 0;
1125 if (m_fd
== INVALID_SOCKET
)
1126 return (wxSOCKET_LOST_FLAG
& flags
);
1128 /* Do not use a static struct, Linux can garble it */
1132 wxFD_ZERO(&readfds
);
1133 wxFD_ZERO(&writefds
);
1134 wxFD_ZERO(&exceptfds
);
1135 wxFD_SET(m_fd
, &readfds
);
1136 if (flags
& wxSOCKET_OUTPUT_FLAG
|| flags
& wxSOCKET_CONNECTION_FLAG
)
1137 wxFD_SET(m_fd
, &writefds
);
1138 wxFD_SET(m_fd
, &exceptfds
);
1140 /* Check 'sticky' CONNECTION flag first */
1141 result
|= wxSOCKET_CONNECTION_FLAG
& m_detected
;
1143 /* If we have already detected a LOST event, then don't try
1144 * to do any further processing.
1146 if ((m_detected
& wxSOCKET_LOST_FLAG
) != 0)
1148 m_establishing
= false;
1149 return (wxSOCKET_LOST_FLAG
& flags
);
1152 /* Try select now */
1153 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
1155 /* What to do here? */
1156 return (result
& flags
);
1159 /* Check for exceptions and errors */
1160 if (wxFD_ISSET(m_fd
, &exceptfds
))
1162 m_establishing
= false;
1163 m_detected
= wxSOCKET_LOST_FLAG
;
1165 /* LOST event: Abort any further processing */
1166 return (wxSOCKET_LOST_FLAG
& flags
);
1169 /* Check for readability */
1170 if (wxFD_ISSET(m_fd
, &readfds
))
1172 result
|= wxSOCKET_INPUT_FLAG
;
1174 if (m_server
&& m_stream
)
1176 /* This is a TCP server socket that detected a connection.
1177 While the INPUT_FLAG is also set, it doesn't matter on
1178 this kind of sockets, as we can only Accept() from them. */
1179 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1183 /* Check for writability */
1184 if (wxFD_ISSET(m_fd
, &writefds
))
1186 if (m_establishing
&& !m_server
)
1189 SOCKOPTLEN_T len
= sizeof(error
);
1190 m_establishing
= false;
1191 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1195 m_detected
= wxSOCKET_LOST_FLAG
;
1197 /* LOST event: Abort any further processing */
1198 return (wxSOCKET_LOST_FLAG
& flags
);
1202 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1207 result
|= wxSOCKET_OUTPUT_FLAG
;
1211 return (result
| m_detected
) & flags
;
1214 // All Wait functions poll the socket using Select() to
1215 // check for the specified combination of conditions, until one
1216 // of these conditions become true, an error occurs, or the
1217 // timeout elapses. The polling loop runs the event loop so that
1218 // this won't block the GUI.
1221 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1223 wxCHECK_MSG( m_impl
, false, "can't wait on invalid socket" );
1225 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1226 m_interrupt
= false;
1229 // Use either the provided timeout or the default timeout value associated
1230 // with this socket.
1232 // TODO: allow waiting forever, see #9443
1233 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1234 : seconds
* 1000 + milliseconds
;
1235 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1237 // Get the active event loop which we'll use for the message dispatching
1238 // when running in the main thread
1239 wxEventLoopBase
*eventLoop
;
1240 if ( wxIsMainThread() )
1242 eventLoop
= wxEventLoop::GetActive();
1244 else // in worker thread
1246 // We never dispatch messages from threads other than the main one.
1250 // reset them before starting to wait
1253 // Wait in an active polling loop: notice that the loop is executed at
1254 // least once, even if timeout is 0 (i.e. polling).
1255 bool gotEvent
= false;
1258 wxSocketEventFlags events
;
1261 // This function is only called if wxSOCKET_BLOCK flag was not used
1262 // and so we should dispatch the events if there is an event loop
1263 // capable of doing it.
1264 if ( eventLoop
->Pending() )
1265 eventLoop
->Dispatch();
1267 events
= m_eventsgot
;
1271 // We always stop waiting when the connection is lost as it doesn't
1272 // make sense to continue further, even if wxSOCKET_LOST_FLAG is
1273 // not specified in flags to wait for.
1274 events
= m_impl
->Select(flags
| wxSOCKET_LOST_FLAG
);
1277 // Incoming connection (server) or connection established (client)?
1278 if ( events
& wxSOCKET_CONNECTION_FLAG
)
1281 m_establishing
= false;
1286 // Data available or output buffer ready?
1287 if ( (events
& wxSOCKET_INPUT_FLAG
) || (events
& wxSOCKET_OUTPUT_FLAG
) )
1294 if ( events
& wxSOCKET_LOST_FLAG
)
1296 m_connected
= false;
1297 m_establishing
= false;
1298 if ( flags
& wxSOCKET_LOST_FLAG
)
1307 const wxMilliClock_t timeNow
= wxGetLocalTimeMillis();
1308 if ( timeNow
>= timeEnd
)
1312 // no event loop or waiting in another thread
1315 // We're busy waiting but at least give up the rest of our current
1319 #endif // wxUSE_THREADS
1325 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1327 return DoWait(seconds
, milliseconds
,
1328 wxSOCKET_INPUT_FLAG
|
1329 wxSOCKET_OUTPUT_FLAG
|
1330 wxSOCKET_CONNECTION_FLAG
|
1335 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1337 // Check pushback buffer before entering DoWait
1341 // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
1342 // because of the semantics of WaitForRead: a return value of true means
1343 // that a Read call will return immediately, not that there is
1344 // actually data to read.
1345 return DoWait(seconds
, milliseconds
, wxSOCKET_INPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1349 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1351 return DoWait(seconds
, milliseconds
, wxSOCKET_OUTPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1354 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1356 return DoWait(seconds
, milliseconds
, wxSOCKET_LOST_FLAG
);
1359 // --------------------------------------------------------------------------
1361 // --------------------------------------------------------------------------
1364 // Get local or peer address
1367 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
1374 peer
= m_impl
->GetPeer();
1376 // copying a null address would just trigger an assert anyway
1381 addr_man
.SetAddress(peer
);
1382 GAddress_destroy(peer
);
1387 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1394 local
= m_impl
->GetLocal();
1395 addr_man
.SetAddress(local
);
1396 GAddress_destroy(local
);
1402 // Save and restore socket state
1405 void wxSocketBase::SaveState()
1407 wxSocketState
*state
;
1409 state
= new wxSocketState();
1411 state
->m_flags
= m_flags
;
1412 state
->m_notify
= m_notify
;
1413 state
->m_eventmask
= m_eventmask
;
1414 state
->m_clientData
= m_clientData
;
1416 m_states
.Append(state
);
1419 void wxSocketBase::RestoreState()
1421 wxList::compatibility_iterator node
;
1422 wxSocketState
*state
;
1424 node
= m_states
.GetLast();
1428 state
= (wxSocketState
*)node
->GetData();
1430 m_flags
= state
->m_flags
;
1431 m_notify
= state
->m_notify
;
1432 m_eventmask
= state
->m_eventmask
;
1433 m_clientData
= state
->m_clientData
;
1435 m_states
.Erase(node
);
1440 // Timeout and flags
1443 void wxSocketBase::SetTimeout(long seconds
)
1445 m_timeout
= seconds
;
1448 m_impl
->SetTimeout(m_timeout
* 1000);
1451 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1453 // Do some sanity checking on the flags used: not all values can be used
1455 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1456 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1457 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1458 "wxSOCKET_NOWAIT doesn't make sense" );
1464 // --------------------------------------------------------------------------
1466 // --------------------------------------------------------------------------
1468 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1470 switch ( notification
)
1472 case wxSOCKET_CONNECTION
:
1473 m_establishing
= false;
1477 // If we are in the middle of a R/W operation, do not
1478 // propagate events to users. Also, filter 'late' events
1479 // which are no longer valid.
1481 case wxSOCKET_INPUT
:
1482 if (m_reading
|| !m_impl
->Select(wxSOCKET_INPUT_FLAG
))
1486 case wxSOCKET_OUTPUT
:
1487 if (m_writing
|| !m_impl
->Select(wxSOCKET_OUTPUT_FLAG
))
1492 m_connected
= false;
1493 m_establishing
= false;
1496 case wxSOCKET_MAX_EVENT
:
1497 wxFAIL_MSG( "unexpected notification" );
1501 wxSocketEventFlags flag
= 0;
1502 switch ( notification
)
1504 case wxSOCKET_INPUT
:
1505 flag
= wxSOCKET_INPUT_FLAG
;
1508 case wxSOCKET_OUTPUT
:
1509 flag
= wxSOCKET_OUTPUT_FLAG
;
1512 case wxSOCKET_CONNECTION
:
1513 flag
= wxSOCKET_CONNECTION_FLAG
;
1517 flag
= wxSOCKET_LOST_FLAG
;
1521 wxFAIL_MSG( "unknown wxSocket notification" );
1524 // remember the events which were generated for this socket, we're going to
1525 // use this in DoWait()
1526 m_eventsgot
|= flag
;
1528 // send the wx event if enabled and we're interested in it
1529 if ( m_notify
&& (m_eventmask
& flag
) && m_handler
)
1531 wxSocketEvent
event(m_id
);
1532 event
.m_event
= notification
;
1533 event
.m_clientData
= m_clientData
;
1534 event
.SetEventObject(this);
1536 m_handler
->AddPendingEvent(event
);
1540 void wxSocketBase::Notify(bool notify
)
1544 m_impl
->Notify(notify
);
1547 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1549 m_eventmask
= flags
;
1552 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1554 m_handler
= &handler
;
1558 // --------------------------------------------------------------------------
1560 // --------------------------------------------------------------------------
1562 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1566 if (m_unread
== NULL
)
1567 m_unread
= malloc(size
);
1572 tmp
= malloc(m_unrd_size
+ size
);
1573 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1579 m_unrd_size
+= size
;
1581 memcpy(m_unread
, buffer
, size
);
1584 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1586 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1591 if (size
> (m_unrd_size
-m_unrd_cur
))
1592 size
= m_unrd_size
-m_unrd_cur
;
1594 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1599 if (m_unrd_size
== m_unrd_cur
)
1612 // ==========================================================================
1614 // ==========================================================================
1616 // --------------------------------------------------------------------------
1618 // --------------------------------------------------------------------------
1620 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1621 wxSocketFlags flags
)
1622 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1624 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1626 m_impl
= wxSocketImpl::Create(*this);
1630 wxLogTrace( wxTRACE_Socket
, _T("*** Failed to create m_impl") );
1634 // Setup the socket as server
1635 m_impl
->Notify(m_notify
);
1636 m_impl
->SetLocal(addr_man
.GetAddress());
1638 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1639 m_impl
->SetReusable();
1641 if (GetFlags() & wxSOCKET_BROADCAST
) {
1642 m_impl
->SetBroadcast();
1644 if (GetFlags() & wxSOCKET_NOBIND
) {
1645 m_impl
->DontDoBind();
1648 if (m_impl
->CreateServer() != wxSOCKET_NOERROR
)
1653 wxLogTrace( wxTRACE_Socket
, _T("*** CreateServer() failed") );
1657 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_impl
->m_fd
);
1660 // --------------------------------------------------------------------------
1662 // --------------------------------------------------------------------------
1664 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1669 // If wait == false, then the call should be nonblocking.
1670 // When we are finished, we put the socket to blocking mode
1672 wxSocketUnblocker
unblock(m_impl
, !wait
);
1673 sock
.m_impl
= m_impl
->WaitConnection(sock
);
1678 sock
.m_type
= wxSOCKET_BASE
;
1679 sock
.m_connected
= true;
1684 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1686 wxSocketBase
* sock
= new wxSocketBase();
1688 sock
->SetFlags(m_flags
);
1690 if (!AcceptWith(*sock
, wait
))
1699 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1701 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
);
1704 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1706 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1708 SOCKOPTLEN_T lenreal
;
1709 if ( getsockopt(m_impl
->m_fd
, level
, optname
,
1710 static_cast<char *>(optval
), &lenreal
) != 0 )
1719 wxSocketBase::SetOption(int level
, int optname
, const void *optval
, int optlen
)
1721 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1723 return setsockopt(m_impl
->m_fd
, level
, optname
,
1724 static_cast<const char *>(optval
), optlen
) == 0;
1727 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1729 GAddress
* la
= local
.GetAddress();
1731 // If the address is valid, save it for use when we call Connect
1732 if (la
&& la
->m_addr
)
1734 m_localAddress
= local
;
1742 // ==========================================================================
1744 // ==========================================================================
1746 // --------------------------------------------------------------------------
1748 // --------------------------------------------------------------------------
1750 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1751 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1753 m_initialRecvBufferSize
=
1754 m_initialSendBufferSize
= -1;
1757 wxSocketClient::~wxSocketClient()
1761 // --------------------------------------------------------------------------
1763 // --------------------------------------------------------------------------
1765 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1766 const wxSockAddress
* local
,
1771 // Shutdown and destroy the socket
1776 m_impl
= wxSocketImpl::Create(*this);
1777 m_connected
= false;
1778 m_establishing
= false;
1783 // If wait == false, then the call should be nonblocking. When we are
1784 // finished, we put the socket to blocking mode again.
1785 wxSocketUnblocker
unblock(m_impl
, !wait
);
1787 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1788 if (GetFlags() & wxSOCKET_REUSEADDR
)
1790 m_impl
->SetReusable();
1792 if (GetFlags() & wxSOCKET_BROADCAST
)
1794 m_impl
->SetBroadcast();
1796 if (GetFlags() & wxSOCKET_NOBIND
)
1798 m_impl
->DontDoBind();
1801 // If no local address was passed and one has been set, use the one that was Set
1802 if (!local
&& m_localAddress
.GetAddress())
1804 local
= &m_localAddress
;
1807 // Bind to the local IP address and port, when provided
1810 GAddress
* la
= local
->GetAddress();
1812 if (la
&& la
->m_addr
)
1813 m_impl
->SetLocal(la
);
1816 m_impl
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1818 m_impl
->SetPeer(addr_man
.GetAddress());
1819 const wxSocketError err
= m_impl
->CreateClient();
1821 //this will register for callbacks - must be called after m_impl->m_fd was initialized
1822 m_impl
->Notify(m_notify
);
1824 if (err
!= wxSOCKET_NOERROR
)
1826 if (err
== wxSOCKET_WOULDBLOCK
)
1827 m_establishing
= true;
1836 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1838 return DoConnect(addr_man
, NULL
, wait
);
1841 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1842 const wxSockAddress
& local
,
1845 return DoConnect(addr_man
, &local
, wait
);
1848 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1852 // this happens if the initial attempt to connect succeeded without
1857 wxCHECK_MSG( m_establishing
&& m_impl
, false,
1858 "No connection establishment attempt in progress" );
1860 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1861 // true if the connection establishment process is finished, whether it is
1862 // over because we successfully connected or because we were not able to
1864 return DoWait(seconds
, milliseconds
,
1865 wxSOCKET_CONNECTION_FLAG
| wxSOCKET_LOST_FLAG
);
1868 // ==========================================================================
1870 // ==========================================================================
1872 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1873 wxSocketFlags flags
)
1874 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1876 // Create the socket
1877 m_impl
= wxSocketImpl::Create(*this);
1882 m_impl
->Notify(m_notify
);
1883 // Setup the socket as non connection oriented
1884 m_impl
->SetLocal(addr
.GetAddress());
1885 if (flags
& wxSOCKET_REUSEADDR
)
1887 m_impl
->SetReusable();
1889 if (GetFlags() & wxSOCKET_BROADCAST
)
1891 m_impl
->SetBroadcast();
1893 if (GetFlags() & wxSOCKET_NOBIND
)
1895 m_impl
->DontDoBind();
1898 if ( m_impl
->CreateUDP() != wxSOCKET_NOERROR
)
1905 // Initialize all stuff
1906 m_connected
= false;
1907 m_establishing
= false;
1910 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1919 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1923 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1925 m_impl
->SetPeer(addr
.GetAddress());
1930 // ==========================================================================
1932 // ==========================================================================
1934 class wxSocketModule
: public wxModule
1937 virtual bool OnInit()
1939 // wxSocketBase will call Initialize() itself only if sockets are
1940 // really used, don't do it from here
1944 virtual void OnExit()
1946 if ( wxSocketBase::IsInitialized() )
1947 wxSocketBase::Shutdown();
1951 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1954 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1956 #endif // wxUSE_SOCKETS