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 // ----------------------------------------------------------------------------
79 void SetTimeValFromMS(timeval
& tv
, unsigned long ms
)
81 tv
.tv_sec
= (ms
/ 1000);
82 tv
.tv_usec
= (ms
% 1000) * 1000;
85 } // anonymous namespace
87 // --------------------------------------------------------------------------
89 // --------------------------------------------------------------------------
91 class wxSocketState
: public wxObject
94 wxSocketFlags m_flags
;
95 wxSocketEventFlags m_eventmask
;
100 wxSocketState() : wxObject() {}
102 DECLARE_NO_COPY_CLASS(wxSocketState
)
105 // Conditionally make the socket non-blocking for the lifetime of this object.
106 class wxSocketUnblocker
109 wxSocketUnblocker(wxSocketImpl
*socket
, bool unblock
= true)
114 m_impl
->SetNonBlocking(true);
120 m_impl
->SetNonBlocking(false);
124 wxSocketImpl
* const m_impl
;
127 DECLARE_NO_COPY_CLASS(wxSocketUnblocker
)
130 // ============================================================================
132 // ============================================================================
134 wxSocketManager
*wxSocketManager::ms_manager
= NULL
;
137 void wxSocketManager::Set(wxSocketManager
*manager
)
139 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
141 ms_manager
= manager
;
145 void wxSocketManager::Init()
147 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
150 Details: Initialize() creates a hidden window as a sink for socket
151 events, such as 'read completed'. wxMSW has only one message loop
152 for the main thread. If Initialize is called in a secondary thread,
153 the socket window will be created for the secondary thread, but
154 since there is no message loop on this thread, it will never
155 receive events and all socket operations will time out.
156 BTW, the main thread must not be stopped using sleep or block
157 on a semaphore (a bad idea in any case) or socket operations
160 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
161 the main thread. Because secondary threads do not have run loops,
162 adding event notifications to the "Current" loop would have no
163 effect at all, events would never fire.
165 wxASSERT_MSG( wxIsMainThread(),
166 "sockets must be initialized from the main thread" );
168 wxAppConsole
* const app
= wxAppConsole::GetInstance();
169 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
171 ms_manager
= app
->GetTraits()->GetSocketManager();
174 // ==========================================================================
176 // ==========================================================================
178 wxSocketImpl::wxSocketImpl(wxSocketBase
& wxsocket
)
179 : m_wxsocket(&wxsocket
)
181 m_fd
= INVALID_SOCKET
;
185 m_error
= wxSOCKET_NOERROR
;
188 m_non_blocking
= false;
190 SetTimeout(wxsocket
.GetTimeout() * 1000);
192 m_establishing
= false;
196 m_initialRecvBufferSize
= -1;
197 m_initialSendBufferSize
= -1;
200 wxSocketImpl::~wxSocketImpl()
202 if (m_fd
!= INVALID_SOCKET
)
206 GAddress_destroy(m_local
);
209 GAddress_destroy(m_peer
);
212 bool wxSocketImpl::PreCreateCheck(GAddress
*addr
)
214 if ( m_fd
!= INVALID_SOCKET
)
216 m_error
= wxSOCKET_INVSOCK
;
220 if ( !addr
|| !addr
->m_addr
)
222 m_error
= wxSOCKET_INVADDR
;
229 void wxSocketImpl::PostCreation()
231 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
233 EnableSocketOption(SO_NOSIGPIPE
);
237 EnableSocketOption(SO_REUSEADDR
);
241 wxASSERT_MSG( !m_stream
, "broadcasting is for datagram sockets only" );
243 EnableSocketOption(SO_BROADCAST
);
246 if ( m_initialRecvBufferSize
>= 0 )
247 SetSocketOption(SO_RCVBUF
, m_initialRecvBufferSize
);
248 if ( m_initialSendBufferSize
>= 0 )
249 SetSocketOption(SO_SNDBUF
, m_initialSendBufferSize
);
251 // FIXME: shouldn't we check for m_non_blocking here? as it is now, all our
252 // sockets are non-blocking
253 UnblockAndRegisterWithEventLoop();
256 wxSocketError
wxSocketImpl::UpdateLocalAddress()
258 WX_SOCKLEN_T lenAddr
= sizeof(*m_local
->m_addr
);
259 if ( getsockname(m_fd
, m_local
->m_addr
, &lenAddr
) != 0 )
262 m_error
= wxSOCKET_IOERR
;
266 m_local
->m_len
= lenAddr
;
268 return wxSOCKET_NOERROR
;
271 wxSocketError
wxSocketImpl::CreateServer()
273 if ( !PreCreateCheck(m_local
) )
279 // do create the socket
280 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
282 if ( m_fd
== INVALID_SOCKET
)
284 m_error
= wxSOCKET_IOERR
;
285 return wxSOCKET_IOERR
;
290 // and then bind to and listen on it
292 // FIXME: should we test for m_dobind here?
293 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
294 m_error
= wxSOCKET_IOERR
;
298 if ( listen(m_fd
, 5) != 0 )
299 m_error
= wxSOCKET_IOERR
;
308 // finally retrieve the address we effectively bound to
309 return UpdateLocalAddress();
312 wxSocketError
wxSocketImpl::CreateClient()
314 if ( !PreCreateCheck(m_peer
) )
317 m_fd
= socket(m_peer
->m_realfamily
, SOCK_STREAM
, 0);
319 if ( m_fd
== INVALID_SOCKET
)
321 m_error
= wxSOCKET_IOERR
;
322 return wxSOCKET_IOERR
;
327 // If a local address has been set, then bind to it before calling connect
328 if ( m_local
&& m_local
->m_addr
)
330 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
333 m_error
= wxSOCKET_IOERR
;
338 // Connect to the peer and handle the EWOULDBLOCK return value in
339 // platform-specific code
340 return DoHandleConnect(connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
));
344 wxSocketError
wxSocketImpl::CreateUDP()
346 if ( !PreCreateCheck(m_local
) )
352 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
354 if ( m_fd
== INVALID_SOCKET
)
356 m_error
= wxSOCKET_IOERR
;
357 return wxSOCKET_IOERR
;
364 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
367 m_error
= wxSOCKET_IOERR
;
371 return UpdateLocalAddress();
374 return wxSOCKET_NOERROR
;
378 void wxSocketImpl::Close()
380 if ( m_fd
!= INVALID_SOCKET
)
383 m_fd
= INVALID_SOCKET
;
388 * Disallow further read/write operations on this socket, close
389 * the fd and disable all callbacks.
391 void wxSocketImpl::Shutdown()
393 if ( m_fd
!= INVALID_SOCKET
)
395 shutdown(m_fd
, 1 /* SD_SEND */);
399 m_detected
= wxSOCKET_LOST_FLAG
;
403 * Sets the timeout for blocking calls. Time is expressed in
406 void wxSocketImpl::SetTimeout(unsigned long millis
)
408 SetTimeValFromMS(m_timeout
, millis
);
411 void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event
)
413 m_wxsocket
->OnRequest(event
);
416 /* Address handling */
419 * Set or get the local or peer address for this socket. The 'set'
420 * functions return wxSOCKET_NOERROR on success, an error code otherwise.
421 * The 'get' functions return a pointer to a GAddress object on success,
422 * or NULL otherwise, in which case they set the error code of the
423 * corresponding socket.
426 * wxSOCKET_INVSOCK - the socket is not valid.
427 * wxSOCKET_INVADDR - the address is not valid.
429 wxSocketError
wxSocketImpl::SetLocal(GAddress
*address
)
431 /* the socket must be initialized, or it must be a server */
432 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
434 m_error
= wxSOCKET_INVSOCK
;
435 return wxSOCKET_INVSOCK
;
439 if (address
== NULL
|| address
->m_family
== wxSOCKET_NOFAMILY
)
441 m_error
= wxSOCKET_INVADDR
;
442 return wxSOCKET_INVADDR
;
446 GAddress_destroy(m_local
);
448 m_local
= GAddress_copy(address
);
450 return wxSOCKET_NOERROR
;
453 wxSocketError
wxSocketImpl::SetPeer(GAddress
*address
)
456 if (address
== NULL
|| address
->m_family
== wxSOCKET_NOFAMILY
)
458 m_error
= wxSOCKET_INVADDR
;
459 return wxSOCKET_INVADDR
;
463 GAddress_destroy(m_peer
);
465 m_peer
= GAddress_copy(address
);
467 return wxSOCKET_NOERROR
;
470 GAddress
*wxSocketImpl::GetLocal()
474 WX_SOCKLEN_T size
= sizeof(addr
);
477 /* try to get it from the m_local var first */
479 return GAddress_copy(m_local
);
481 /* else, if the socket is initialized, try getsockname */
482 if (m_fd
== INVALID_SOCKET
)
484 m_error
= wxSOCKET_INVSOCK
;
488 if (getsockname(m_fd
, (sockaddr
*)&addr
, &size
) == SOCKET_ERROR
)
490 m_error
= wxSOCKET_IOERR
;
494 /* got a valid address from getsockname, create a GAddress object */
495 if ((address
= GAddress_new()) == NULL
)
497 m_error
= wxSOCKET_MEMERR
;
501 if ((err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
)) != wxSOCKET_NOERROR
)
503 GAddress_destroy(address
);
511 GAddress
*wxSocketImpl::GetPeer()
513 /* try to get it from the m_peer var */
515 return GAddress_copy(m_peer
);
520 bool wxSocketImpl::DoBlockWithTimeout(wxSocketEventFlags flags
)
522 if ( !m_non_blocking
)
526 wxFD_SET(m_fd
, &fds
);
529 *readfds
= flags
& wxSOCKET_INPUT_FLAG
? &fds
: NULL
,
530 *writefds
= flags
& wxSOCKET_OUTPUT_FLAG
? &fds
: NULL
;
532 // make a copy as it can be modified by select()
533 struct timeval tv
= m_timeout
;
534 int ret
= select(m_fd
+ 1, readfds
, writefds
, NULL
, &tv
);
539 m_error
= wxSOCKET_TIMEDOUT
;
543 m_error
= wxSOCKET_IOERR
;
547 //else: we're non-blocking, never block
552 // ==========================================================================
554 // ==========================================================================
556 // --------------------------------------------------------------------------
557 // Initialization and shutdown
558 // --------------------------------------------------------------------------
560 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
561 // to m_countInit with a crit section
562 size_t wxSocketBase::m_countInit
= 0;
564 bool wxSocketBase::IsInitialized()
566 return m_countInit
> 0;
569 bool wxSocketBase::Initialize()
571 if ( !m_countInit
++ )
573 wxSocketManager
* const manager
= wxSocketManager::Get();
574 if ( !manager
|| !manager
->OnInit() )
585 void wxSocketBase::Shutdown()
587 // we should be initialized
588 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
589 if ( --m_countInit
== 0 )
591 wxSocketManager
* const manager
= wxSocketManager::Get();
592 wxCHECK_RET( manager
, "should have a socket manager" );
598 // --------------------------------------------------------------------------
600 // --------------------------------------------------------------------------
602 void wxSocketBase::Init()
605 m_type
= wxSOCKET_UNINIT
;
617 m_beingDeleted
= false;
632 if ( !IsInitialized() )
634 // this Initialize() will be undone by wxSocketModule::OnExit(), all
635 // the other calls to it should be matched by a call to Shutdown()
640 wxSocketBase::wxSocketBase()
645 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
654 wxSocketBase::~wxSocketBase()
656 // Just in case the app called Destroy() *and* then deleted the socket
657 // immediately: don't leave dangling pointers.
658 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
660 traits
->RemoveFromPendingDelete(this);
662 // Shutdown and close the socket
666 // Destroy the implementation object
669 // Free the pushback buffer
674 bool wxSocketBase::Destroy()
676 // Delayed destruction: the socket will be deleted during the next idle
677 // loop iteration. This ensures that all pending events have been
679 m_beingDeleted
= true;
681 // Shutdown and close the socket
684 // Suppress events from now on
687 // schedule this object for deletion
688 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
691 // let the traits object decide what to do with us
692 traits
->ScheduleForDestroy(this);
694 else // no app or no traits
696 // in wxBase we might have no app object at all, don't leak memory
703 // ----------------------------------------------------------------------------
705 // ----------------------------------------------------------------------------
707 wxSocketError
wxSocketBase::LastError() const
709 return m_impl
->GetError();
712 // --------------------------------------------------------------------------
714 // --------------------------------------------------------------------------
716 // The following IO operations update m_error and m_lcount:
717 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
719 // TODO: Should Connect, Accept and AcceptWith update m_error?
721 bool wxSocketBase::Close()
723 // Interrupt pending waits
730 m_establishing
= false;
734 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
739 m_lcount
= DoRead(buffer
, nbytes
);
741 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
742 if (m_flags
& wxSOCKET_WAITALL
)
743 m_error
= (m_lcount
!= nbytes
);
745 m_error
= (m_lcount
== 0);
747 // Allow read events from now on
753 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
755 // We use pointer arithmetic here which doesn't work with void pointers.
756 char *buffer
= static_cast<char *>(buffer_
);
758 // Try the push back buffer first, even before checking whether the socket
759 // is valid to allow reading previously pushed back data from an already
761 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
765 // If it's indeed closed or if read everything, there is nothing more to do.
766 if ( !m_impl
|| !nbytes
)
769 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
772 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
773 // polling the socket and don't block at all.
774 if ( m_flags
& wxSOCKET_NOWAIT
)
776 wxSocketUnblocker
unblock(m_impl
);
777 int ret
= m_impl
->Read(buffer
, nbytes
);
783 else // blocking socket
787 // Wait until socket becomes ready for reading dispatching the GUI
788 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
789 // specified to disable this.
790 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
793 const int ret
= m_impl
->Read(buffer
, nbytes
);
796 // for connection-oriented (e.g. TCP) sockets we can only read
797 // 0 bytes if the other end has been closed, and for
798 // connectionless ones (UDP) this flag doesn't make sense
799 // anyhow so we can set it to true too without doing any harm
806 // this will be always interpreted as error by Read()
812 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
813 // something and we don't need to wait for all nbytes bytes to be
815 if ( !(m_flags
& wxSOCKET_WAITALL
) )
818 // Otherwise continue reading until we do read everything.
830 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
832 wxUint32 len
, len2
, sig
, total
;
837 unsigned char sig
[4];
838 unsigned char len
[4];
847 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
849 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
852 sig
= (wxUint32
)msg
.sig
[0];
853 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
854 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
855 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
857 if (sig
!= 0xfeeddead)
859 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
863 len
= (wxUint32
)msg
.len
[0];
864 len
|= (wxUint32
)(msg
.len
[1] << 8);
865 len
|= (wxUint32
)(msg
.len
[2] << 16);
866 len
|= (wxUint32
)(msg
.len
[3] << 24);
876 // Don't attempt to read if the msg was zero bytes long.
879 total
= DoRead(buffer
, len
);
887 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
890 // NOTE: discarded bytes don't add to m_lcount.
893 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
894 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
895 len2
-= (wxUint32
)discard_len
;
897 while ((discard_len
> 0) && len2
);
899 delete [] discard_buffer
;
904 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
907 sig
= (wxUint32
)msg
.sig
[0];
908 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
909 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
910 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
912 if (sig
!= 0xdeadfeed)
914 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
930 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
935 m_lcount
= DoRead(buffer
, nbytes
);
936 Pushback(buffer
, m_lcount
);
938 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
939 if (m_flags
& wxSOCKET_WAITALL
)
940 m_error
= (m_lcount
!= nbytes
);
942 m_error
= (m_lcount
== 0);
944 // Allow read events again
950 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
955 m_lcount
= DoWrite(buffer
, nbytes
);
957 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
958 if (m_flags
& wxSOCKET_WAITALL
)
959 m_error
= (m_lcount
!= nbytes
);
961 m_error
= (m_lcount
== 0);
963 // Allow write events again
969 // This function is a mirror image of DoRead() except that it doesn't use the
970 // push back buffer, please see comments there
971 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
973 const char *buffer
= static_cast<const char *>(buffer_
);
975 // Return if there is nothing to read or the socket is (already?) closed.
976 if ( !m_impl
|| !nbytes
)
979 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
982 if ( m_flags
& wxSOCKET_NOWAIT
)
984 wxSocketUnblocker
unblock(m_impl
);
985 const int ret
= m_impl
->Write(buffer
, nbytes
);
989 else // blocking socket
993 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
996 const int ret
= m_impl
->Write(buffer
, nbytes
);
1007 if ( !(m_flags
& wxSOCKET_WAITALL
) )
1021 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
1027 unsigned char sig
[4];
1028 unsigned char len
[4];
1031 // Mask write events
1036 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
1038 msg
.sig
[0] = (unsigned char) 0xad;
1039 msg
.sig
[1] = (unsigned char) 0xde;
1040 msg
.sig
[2] = (unsigned char) 0xed;
1041 msg
.sig
[3] = (unsigned char) 0xfe;
1043 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
1044 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
1045 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
1046 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
1048 if (DoWrite(&msg
, sizeof(msg
)) < sizeof(msg
))
1051 total
= DoWrite(buffer
, nbytes
);
1056 msg
.sig
[0] = (unsigned char) 0xed;
1057 msg
.sig
[1] = (unsigned char) 0xfe;
1058 msg
.sig
[2] = (unsigned char) 0xad;
1059 msg
.sig
[3] = (unsigned char) 0xde;
1063 msg
.len
[3] = (char) 0;
1065 if ((DoWrite(&msg
, sizeof(msg
))) < sizeof(msg
))
1068 // everything was OK
1079 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
1082 Pushback(buffer
, nbytes
);
1090 wxSocketBase
& wxSocketBase::Discard()
1092 char *buffer
= new char[MAX_DISCARD_SIZE
];
1099 SetFlags(wxSOCKET_NOWAIT
);
1103 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
1106 while (ret
== MAX_DISCARD_SIZE
);
1112 // Allow read events again
1118 // --------------------------------------------------------------------------
1120 // --------------------------------------------------------------------------
1123 This function will check for the events specified in the flags parameter,
1124 and it will return a mask indicating which operations can be performed.
1126 wxSocketEventFlags
wxSocketImpl::Select(wxSocketEventFlags flags
,
1127 unsigned long timeout
)
1129 wxSocketEventFlags result
= 0;
1131 if (m_fd
== INVALID_SOCKET
)
1132 return (wxSOCKET_LOST_FLAG
& flags
);
1135 SetTimeValFromMS(tv
, timeout
);
1140 wxFD_ZERO(&readfds
);
1141 wxFD_ZERO(&writefds
);
1142 wxFD_ZERO(&exceptfds
);
1143 wxFD_SET(m_fd
, &readfds
);
1144 if (flags
& wxSOCKET_OUTPUT_FLAG
|| flags
& wxSOCKET_CONNECTION_FLAG
)
1145 wxFD_SET(m_fd
, &writefds
);
1146 wxFD_SET(m_fd
, &exceptfds
);
1148 /* Check 'sticky' CONNECTION flag first */
1149 result
|= wxSOCKET_CONNECTION_FLAG
& m_detected
;
1151 /* If we have already detected a LOST event, then don't try
1152 * to do any further processing.
1154 if ((m_detected
& wxSOCKET_LOST_FLAG
) != 0)
1156 m_establishing
= false;
1157 return (wxSOCKET_LOST_FLAG
& flags
);
1160 /* Try select now */
1161 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
1163 /* What to do here? */
1164 return (result
& flags
);
1167 /* Check for exceptions and errors */
1168 if (wxFD_ISSET(m_fd
, &exceptfds
))
1170 m_establishing
= false;
1171 m_detected
= wxSOCKET_LOST_FLAG
;
1173 /* LOST event: Abort any further processing */
1174 return (wxSOCKET_LOST_FLAG
& flags
);
1177 /* Check for readability */
1178 if (wxFD_ISSET(m_fd
, &readfds
))
1180 result
|= wxSOCKET_INPUT_FLAG
;
1182 if (m_server
&& m_stream
)
1184 /* This is a TCP server socket that detected a connection.
1185 While the INPUT_FLAG is also set, it doesn't matter on
1186 this kind of sockets, as we can only Accept() from them. */
1187 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1191 /* Check for writability */
1192 if (wxFD_ISSET(m_fd
, &writefds
))
1194 if (m_establishing
&& !m_server
)
1197 SOCKOPTLEN_T len
= sizeof(error
);
1198 m_establishing
= false;
1199 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1203 m_detected
= wxSOCKET_LOST_FLAG
;
1205 /* LOST event: Abort any further processing */
1206 return (wxSOCKET_LOST_FLAG
& flags
);
1210 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1215 result
|= wxSOCKET_OUTPUT_FLAG
;
1219 return (result
| m_detected
) & flags
;
1223 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1225 wxCHECK_MSG( m_impl
, false, "can't wait on invalid socket" );
1227 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1228 m_interrupt
= false;
1231 // Use either the provided timeout or the default timeout value associated
1232 // with this socket.
1234 // TODO: allow waiting forever, see #9443
1235 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1236 : seconds
* 1000 + milliseconds
;
1237 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1239 // Get the active event loop which we'll use for the message dispatching
1240 // when running in the main thread
1241 wxEventLoopBase
*eventLoop
;
1242 if ( wxIsMainThread() )
1244 eventLoop
= wxEventLoop::GetActive();
1246 else // in worker thread
1248 // We never dispatch messages from threads other than the main one.
1252 // Wait until we receive the event we're waiting for or the timeout expires
1253 // (but note that we always execute the loop at least once, even if timeout
1254 // is 0 as this is used for polling)
1255 bool gotEvent
= false;
1256 for ( bool firstTime
= true; !m_interrupt
; firstTime
= false )
1258 long timeLeft
= wxMilliClockToLong(timeEnd
- wxGetLocalTimeMillis());
1267 // This function is only called if wxSOCKET_BLOCK flag was not used and
1268 // so we should dispatch the events if there is an event loop capable
1270 wxSocketEventFlags events
;
1273 // reset them before starting to wait
1276 eventLoop
->DispatchTimeout(timeLeft
);
1278 events
= m_eventsgot
;
1280 else // no event loop or waiting in another thread
1282 // as explained below, we should always check for wxSOCKET_LOST_FLAG
1283 events
= m_impl
->Select(flags
| wxSOCKET_LOST_FLAG
, timeLeft
);
1286 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1287 // it, as continuing to wait for anything else after getting it is
1289 if ( events
& wxSOCKET_LOST_FLAG
)
1291 m_connected
= false;
1292 m_establishing
= false;
1293 if ( flags
& wxSOCKET_LOST_FLAG
)
1298 // otherwise mask out the bits we're not interested in
1301 // Incoming connection (server) or connection established (client)?
1302 if ( events
& wxSOCKET_CONNECTION_FLAG
)
1305 m_establishing
= false;
1310 // Data available or output buffer ready?
1311 if ( (events
& wxSOCKET_INPUT_FLAG
) || (events
& wxSOCKET_OUTPUT_FLAG
) )
1321 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1323 return DoWait(seconds
, milliseconds
,
1324 wxSOCKET_INPUT_FLAG
|
1325 wxSOCKET_OUTPUT_FLAG
|
1326 wxSOCKET_CONNECTION_FLAG
|
1331 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1333 // Check pushback buffer before entering DoWait
1337 // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
1338 // because of the semantics of WaitForRead: a return value of true means
1339 // that a Read call will return immediately, not that there is
1340 // actually data to read.
1341 return DoWait(seconds
, milliseconds
, wxSOCKET_INPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1345 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1347 return DoWait(seconds
, milliseconds
, wxSOCKET_OUTPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1350 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1352 return DoWait(seconds
, milliseconds
, wxSOCKET_LOST_FLAG
);
1355 // --------------------------------------------------------------------------
1357 // --------------------------------------------------------------------------
1360 // Get local or peer address
1363 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
1370 peer
= m_impl
->GetPeer();
1372 // copying a null address would just trigger an assert anyway
1377 addr_man
.SetAddress(peer
);
1378 GAddress_destroy(peer
);
1383 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1390 local
= m_impl
->GetLocal();
1391 addr_man
.SetAddress(local
);
1392 GAddress_destroy(local
);
1398 // Save and restore socket state
1401 void wxSocketBase::SaveState()
1403 wxSocketState
*state
;
1405 state
= new wxSocketState();
1407 state
->m_flags
= m_flags
;
1408 state
->m_notify
= m_notify
;
1409 state
->m_eventmask
= m_eventmask
;
1410 state
->m_clientData
= m_clientData
;
1412 m_states
.Append(state
);
1415 void wxSocketBase::RestoreState()
1417 wxList::compatibility_iterator node
;
1418 wxSocketState
*state
;
1420 node
= m_states
.GetLast();
1424 state
= (wxSocketState
*)node
->GetData();
1426 m_flags
= state
->m_flags
;
1427 m_notify
= state
->m_notify
;
1428 m_eventmask
= state
->m_eventmask
;
1429 m_clientData
= state
->m_clientData
;
1431 m_states
.Erase(node
);
1436 // Timeout and flags
1439 void wxSocketBase::SetTimeout(long seconds
)
1441 m_timeout
= seconds
;
1444 m_impl
->SetTimeout(m_timeout
* 1000);
1447 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1449 // Do some sanity checking on the flags used: not all values can be used
1451 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1452 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1453 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1454 "wxSOCKET_NOWAIT doesn't make sense" );
1460 // --------------------------------------------------------------------------
1462 // --------------------------------------------------------------------------
1464 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1466 wxSocketEventFlags flag
= 0;
1467 switch ( notification
)
1469 case wxSOCKET_INPUT
:
1470 flag
= wxSOCKET_INPUT_FLAG
;
1473 case wxSOCKET_OUTPUT
:
1474 flag
= wxSOCKET_OUTPUT_FLAG
;
1477 case wxSOCKET_CONNECTION
:
1478 flag
= wxSOCKET_CONNECTION_FLAG
;
1482 flag
= wxSOCKET_LOST_FLAG
;
1486 wxFAIL_MSG( "unknown wxSocket notification" );
1489 // if we lost the connection the socket is now closed
1490 if ( notification
== wxSOCKET_LOST
)
1493 // remember the events which were generated for this socket, we're going to
1494 // use this in DoWait()
1495 m_eventsgot
|= flag
;
1497 // send the wx event if enabled and we're interested in it
1498 if ( m_notify
&& (m_eventmask
& flag
) && m_handler
)
1500 // If we are in the middle of a R/W operation, do not propagate events
1501 // to users. Also, filter 'late' events which are no longer valid.
1502 if ( notification
== wxSOCKET_INPUT
)
1504 if ( m_reading
|| !m_impl
->Select(wxSOCKET_INPUT_FLAG
) )
1507 else if ( notification
== wxSOCKET_OUTPUT
)
1509 if ( m_writing
|| !m_impl
->Select(wxSOCKET_OUTPUT_FLAG
) )
1513 wxSocketEvent
event(m_id
);
1514 event
.m_event
= notification
;
1515 event
.m_clientData
= m_clientData
;
1516 event
.SetEventObject(this);
1518 m_handler
->AddPendingEvent(event
);
1522 void wxSocketBase::Notify(bool 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
->SetLocal(addr_man
.GetAddress());
1617 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1618 m_impl
->SetReusable();
1620 if (GetFlags() & wxSOCKET_BROADCAST
) {
1621 m_impl
->SetBroadcast();
1623 if (GetFlags() & wxSOCKET_NOBIND
) {
1624 m_impl
->DontDoBind();
1627 if (m_impl
->CreateServer() != wxSOCKET_NOERROR
)
1632 wxLogTrace( wxTRACE_Socket
, _T("*** CreateServer() failed") );
1636 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_impl
->m_fd
);
1639 // --------------------------------------------------------------------------
1641 // --------------------------------------------------------------------------
1643 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1648 // If wait == false, then the call should be nonblocking.
1649 // When we are finished, we put the socket to blocking mode
1651 wxSocketUnblocker
unblock(m_impl
, !wait
);
1652 sock
.m_impl
= m_impl
->WaitConnection(sock
);
1657 sock
.m_type
= wxSOCKET_BASE
;
1658 sock
.m_connected
= true;
1663 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1665 wxSocketBase
* sock
= new wxSocketBase();
1667 sock
->SetFlags(m_flags
);
1669 if (!AcceptWith(*sock
, wait
))
1678 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1680 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
);
1683 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1685 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1687 SOCKOPTLEN_T lenreal
= *optlen
;
1688 if ( getsockopt(m_impl
->m_fd
, level
, optname
,
1689 static_cast<char *>(optval
), &lenreal
) != 0 )
1698 wxSocketBase::SetOption(int level
, int optname
, const void *optval
, int optlen
)
1700 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1702 return setsockopt(m_impl
->m_fd
, level
, optname
,
1703 static_cast<const char *>(optval
), optlen
) == 0;
1706 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1708 GAddress
* la
= local
.GetAddress();
1710 // If the address is valid, save it for use when we call Connect
1711 if (la
&& la
->m_addr
)
1713 m_localAddress
= local
;
1721 // ==========================================================================
1723 // ==========================================================================
1725 // --------------------------------------------------------------------------
1727 // --------------------------------------------------------------------------
1729 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1730 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1732 m_initialRecvBufferSize
=
1733 m_initialSendBufferSize
= -1;
1736 wxSocketClient::~wxSocketClient()
1740 // --------------------------------------------------------------------------
1742 // --------------------------------------------------------------------------
1744 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1745 const wxSockAddress
* local
,
1750 // Shutdown and destroy the socket
1755 m_impl
= wxSocketImpl::Create(*this);
1756 m_connected
= false;
1757 m_establishing
= false;
1762 // If wait == false, then the call should be nonblocking. When we are
1763 // finished, we put the socket to blocking mode again.
1764 wxSocketUnblocker
unblock(m_impl
, !wait
);
1766 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1767 if (GetFlags() & wxSOCKET_REUSEADDR
)
1769 m_impl
->SetReusable();
1771 if (GetFlags() & wxSOCKET_BROADCAST
)
1773 m_impl
->SetBroadcast();
1775 if (GetFlags() & wxSOCKET_NOBIND
)
1777 m_impl
->DontDoBind();
1780 // If no local address was passed and one has been set, use the one that was Set
1781 if (!local
&& m_localAddress
.GetAddress())
1783 local
= &m_localAddress
;
1786 // Bind to the local IP address and port, when provided
1789 GAddress
* la
= local
->GetAddress();
1791 if (la
&& la
->m_addr
)
1792 m_impl
->SetLocal(la
);
1795 m_impl
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1797 m_impl
->SetPeer(addr_man
.GetAddress());
1798 const wxSocketError err
= m_impl
->CreateClient();
1800 if (err
!= wxSOCKET_NOERROR
)
1802 if (err
== wxSOCKET_WOULDBLOCK
)
1803 m_establishing
= true;
1812 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1814 return DoConnect(addr_man
, NULL
, wait
);
1817 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1818 const wxSockAddress
& local
,
1821 return DoConnect(addr_man
, &local
, wait
);
1824 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1828 // this happens if the initial attempt to connect succeeded without
1833 wxCHECK_MSG( m_establishing
&& m_impl
, false,
1834 "No connection establishment attempt in progress" );
1836 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1837 // true if the connection establishment process is finished, whether it is
1838 // over because we successfully connected or because we were not able to
1840 return DoWait(seconds
, milliseconds
,
1841 wxSOCKET_CONNECTION_FLAG
| wxSOCKET_LOST_FLAG
);
1844 // ==========================================================================
1846 // ==========================================================================
1848 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1849 wxSocketFlags flags
)
1850 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1852 // Create the socket
1853 m_impl
= wxSocketImpl::Create(*this);
1858 // Setup the socket as non connection oriented
1859 m_impl
->SetLocal(addr
.GetAddress());
1860 if (flags
& wxSOCKET_REUSEADDR
)
1862 m_impl
->SetReusable();
1864 if (GetFlags() & wxSOCKET_BROADCAST
)
1866 m_impl
->SetBroadcast();
1868 if (GetFlags() & wxSOCKET_NOBIND
)
1870 m_impl
->DontDoBind();
1873 if ( m_impl
->CreateUDP() != wxSOCKET_NOERROR
)
1880 // Initialize all stuff
1881 m_connected
= false;
1882 m_establishing
= false;
1885 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1894 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1898 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1900 m_impl
->SetPeer(addr
.GetAddress());
1905 // ==========================================================================
1907 // ==========================================================================
1909 class wxSocketModule
: public wxModule
1912 virtual bool OnInit()
1914 // wxSocketBase will call Initialize() itself only if sockets are
1915 // really used, don't do it from here
1919 virtual void OnExit()
1921 if ( wxSocketBase::IsInitialized() )
1922 wxSocketBase::Shutdown();
1926 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1929 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1931 #endif // wxUSE_SOCKETS