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 // ==========================================================================
164 wxSocketImpl
*wxSocketImpl::Create(wxSocketBase
& wxsocket
)
166 wxSocketManager
* const manager
= wxSocketManager::Get();
167 return manager
? manager
->CreateSocket(wxsocket
) : NULL
;
170 wxSocketImpl::wxSocketImpl(wxSocketBase
& wxsocket
)
171 : m_wxsocket(&wxsocket
)
173 m_fd
= INVALID_SOCKET
;
177 m_error
= wxSOCKET_NOERROR
;
180 m_non_blocking
= false;
182 SetTimeout(wxsocket
.GetTimeout() * 1000);
184 m_establishing
= false;
188 m_initialRecvBufferSize
= -1;
189 m_initialSendBufferSize
= -1;
192 wxSocketImpl::~wxSocketImpl()
194 if (m_fd
!= INVALID_SOCKET
)
198 GAddress_destroy(m_local
);
201 GAddress_destroy(m_peer
);
204 bool wxSocketImpl::PreCreateCheck(GAddress
*addr
)
206 if ( m_fd
!= INVALID_SOCKET
)
208 m_error
= wxSOCKET_INVSOCK
;
212 if ( !addr
|| !addr
->m_addr
)
214 m_error
= wxSOCKET_INVADDR
;
221 void wxSocketImpl::PostCreation()
223 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
225 EnableSocketOption(SO_NOSIGPIPE
);
229 EnableSocketOption(SO_REUSEADDR
);
233 wxASSERT_MSG( !m_stream
, "broadcasting is for datagram sockets only" );
235 EnableSocketOption(SO_BROADCAST
);
238 if ( m_initialRecvBufferSize
>= 0 )
239 SetSocketOption(SO_RCVBUF
, m_initialRecvBufferSize
);
240 if ( m_initialSendBufferSize
>= 0 )
241 SetSocketOption(SO_SNDBUF
, m_initialSendBufferSize
);
243 // FIXME: shouldn't we check for m_non_blocking here? as it is now, all our
244 // sockets are non-blocking
245 UnblockAndRegisterWithEventLoop();
248 wxSocketError
wxSocketImpl::UpdateLocalAddress()
250 WX_SOCKLEN_T lenAddr
;
251 if ( getsockname(m_fd
, m_local
->m_addr
, &lenAddr
) != 0 )
254 m_error
= wxSOCKET_IOERR
;
258 m_local
->m_len
= lenAddr
;
260 return wxSOCKET_NOERROR
;
263 wxSocketError
wxSocketImpl::CreateServer()
265 if ( !PreCreateCheck(m_local
) )
271 // do create the socket
272 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
274 if ( m_fd
== INVALID_SOCKET
)
276 m_error
= wxSOCKET_IOERR
;
277 return wxSOCKET_IOERR
;
282 // and then bind to and listen on it
284 // FIXME: should we test for m_dobind here?
285 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
286 m_error
= wxSOCKET_IOERR
;
290 if ( listen(m_fd
, 5) != 0 )
291 m_error
= wxSOCKET_IOERR
;
300 // finally retrieve the address we effectively bound to
301 return UpdateLocalAddress();
304 wxSocketError
wxSocketImpl::CreateClient()
306 if ( !PreCreateCheck(m_peer
) )
309 m_fd
= socket(m_peer
->m_realfamily
, SOCK_STREAM
, 0);
311 if ( m_fd
== INVALID_SOCKET
)
313 m_error
= wxSOCKET_IOERR
;
314 return wxSOCKET_IOERR
;
319 // If a local address has been set, then bind to it before calling connect
320 if ( m_local
&& m_local
->m_addr
)
322 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
325 m_error
= wxSOCKET_IOERR
;
330 // Connect to the peer and handle the EWOULDBLOCK return value in
331 // platform-specific code
332 return DoHandleConnect(connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
));
336 wxSocketError
wxSocketImpl::CreateUDP()
338 if ( !PreCreateCheck(m_local
) )
344 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
346 if ( m_fd
== INVALID_SOCKET
)
348 m_error
= wxSOCKET_IOERR
;
349 return wxSOCKET_IOERR
;
356 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
359 m_error
= wxSOCKET_IOERR
;
363 return UpdateLocalAddress();
366 return wxSOCKET_NOERROR
;
370 void wxSocketImpl::Close()
372 if ( m_fd
!= INVALID_SOCKET
)
375 m_fd
= INVALID_SOCKET
;
380 * Disallow further read/write operations on this socket, close
381 * the fd and disable all callbacks.
383 void wxSocketImpl::Shutdown()
385 if ( m_fd
!= INVALID_SOCKET
)
387 shutdown(m_fd
, 1 /* SD_SEND */);
391 m_detected
= wxSOCKET_LOST_FLAG
;
395 * Sets the timeout for blocking calls. Time is expressed in
398 void wxSocketImpl::SetTimeout(unsigned long millis
)
400 m_timeout
.tv_sec
= (millis
/ 1000);
401 m_timeout
.tv_usec
= (millis
% 1000) * 1000;
404 void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event
)
406 m_wxsocket
->OnRequest(event
);
409 /* Address handling */
412 * Set or get the local or peer address for this socket. The 'set'
413 * functions return wxSOCKET_NOERROR on success, an error code otherwise.
414 * The 'get' functions return a pointer to a GAddress object on success,
415 * or NULL otherwise, in which case they set the error code of the
416 * corresponding socket.
419 * wxSOCKET_INVSOCK - the socket is not valid.
420 * wxSOCKET_INVADDR - the address is not valid.
422 wxSocketError
wxSocketImpl::SetLocal(GAddress
*address
)
424 /* the socket must be initialized, or it must be a server */
425 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
427 m_error
= wxSOCKET_INVSOCK
;
428 return wxSOCKET_INVSOCK
;
432 if (address
== NULL
|| address
->m_family
== wxSOCKET_NOFAMILY
)
434 m_error
= wxSOCKET_INVADDR
;
435 return wxSOCKET_INVADDR
;
439 GAddress_destroy(m_local
);
441 m_local
= GAddress_copy(address
);
443 return wxSOCKET_NOERROR
;
446 wxSocketError
wxSocketImpl::SetPeer(GAddress
*address
)
449 if (address
== NULL
|| address
->m_family
== wxSOCKET_NOFAMILY
)
451 m_error
= wxSOCKET_INVADDR
;
452 return wxSOCKET_INVADDR
;
456 GAddress_destroy(m_peer
);
458 m_peer
= GAddress_copy(address
);
460 return wxSOCKET_NOERROR
;
463 GAddress
*wxSocketImpl::GetLocal()
467 WX_SOCKLEN_T size
= sizeof(addr
);
470 /* try to get it from the m_local var first */
472 return GAddress_copy(m_local
);
474 /* else, if the socket is initialized, try getsockname */
475 if (m_fd
== INVALID_SOCKET
)
477 m_error
= wxSOCKET_INVSOCK
;
481 if (getsockname(m_fd
, (sockaddr
*)&addr
, &size
) == SOCKET_ERROR
)
483 m_error
= wxSOCKET_IOERR
;
487 /* got a valid address from getsockname, create a GAddress object */
488 if ((address
= GAddress_new()) == NULL
)
490 m_error
= wxSOCKET_MEMERR
;
494 if ((err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
)) != wxSOCKET_NOERROR
)
496 GAddress_destroy(address
);
504 GAddress
*wxSocketImpl::GetPeer()
506 /* try to get it from the m_peer var */
508 return GAddress_copy(m_peer
);
513 // ==========================================================================
515 // ==========================================================================
517 // --------------------------------------------------------------------------
518 // Initialization and shutdown
519 // --------------------------------------------------------------------------
521 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
522 // to m_countInit with a crit section
523 size_t wxSocketBase::m_countInit
= 0;
525 bool wxSocketBase::IsInitialized()
527 return m_countInit
> 0;
530 bool wxSocketBase::Initialize()
532 if ( !m_countInit
++ )
534 wxSocketManager
* const manager
= wxSocketManager::Get();
535 if ( !manager
|| !manager
->OnInit() )
546 void wxSocketBase::Shutdown()
548 // we should be initialized
549 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
550 if ( --m_countInit
== 0 )
552 wxSocketManager
* const manager
= wxSocketManager::Get();
553 wxCHECK_RET( manager
, "should have a socket manager" );
559 // --------------------------------------------------------------------------
561 // --------------------------------------------------------------------------
563 void wxSocketBase::Init()
566 m_type
= wxSOCKET_UNINIT
;
578 m_beingDeleted
= false;
592 if ( !IsInitialized() )
594 // this Initialize() will be undone by wxSocketModule::OnExit(), all
595 // the other calls to it should be matched by a call to Shutdown()
600 wxSocketBase::wxSocketBase()
605 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
614 wxSocketBase::~wxSocketBase()
616 // Just in case the app called Destroy() *and* then deleted the socket
617 // immediately: don't leave dangling pointers.
618 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
620 traits
->RemoveFromPendingDelete(this);
622 // Shutdown and close the socket
626 // Destroy the implementation object
629 // Free the pushback buffer
634 bool wxSocketBase::Destroy()
636 // Delayed destruction: the socket will be deleted during the next idle
637 // loop iteration. This ensures that all pending events have been
639 m_beingDeleted
= true;
641 // Shutdown and close the socket
644 // Supress events from now on
647 // schedule this object for deletion
648 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
651 // let the traits object decide what to do with us
652 traits
->ScheduleForDestroy(this);
654 else // no app or no traits
656 // in wxBase we might have no app object at all, don't leak memory
663 // ----------------------------------------------------------------------------
665 // ----------------------------------------------------------------------------
667 wxSocketError
wxSocketBase::LastError() const
669 return m_impl
->GetError();
672 // --------------------------------------------------------------------------
674 // --------------------------------------------------------------------------
676 // The following IO operations update m_error and m_lcount:
677 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
679 // TODO: Should Connect, Accept and AcceptWith update m_error?
681 bool wxSocketBase::Close()
683 // Interrupt pending waits
690 m_establishing
= false;
694 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
699 m_lcount
= DoRead(buffer
, nbytes
);
701 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
702 if (m_flags
& wxSOCKET_WAITALL
)
703 m_error
= (m_lcount
!= nbytes
);
705 m_error
= (m_lcount
== 0);
707 // Allow read events from now on
713 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
715 // We use pointer arithmetic here which doesn't work with void pointers.
716 char *buffer
= static_cast<char *>(buffer_
);
718 // Try the push back buffer first, even before checking whether the socket
719 // is valid to allow reading previously pushed back data from an already
721 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
725 // If it's indeed closed or if read everything, there is nothing more to do.
726 if ( !m_impl
|| !nbytes
)
729 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
732 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
733 // polling the socket and don't block at all.
734 if ( m_flags
& wxSOCKET_NOWAIT
)
736 wxSocketUnblocker
unblock(m_impl
);
737 int ret
= m_impl
->Read(buffer
, nbytes
);
743 else // blocking socket
747 // Wait until socket becomes ready for reading dispatching the GUI
748 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
749 // specified to disable this.
750 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
753 const int ret
= m_impl
->Read(buffer
, nbytes
);
756 // for connection-oriented (e.g. TCP) sockets we can only read
757 // 0 bytes if the other end has been closed, and for
758 // connectionless ones (UDP) this flag doesn't make sense
759 // anyhow so we can set it to true too without doing any harm
766 // this will be always interpreted as error by Read()
772 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
773 // something and we don't need to wait for all nbytes bytes to be
775 if ( !(m_flags
& wxSOCKET_WAITALL
) )
778 // Otherwise continue reading until we do read everything.
790 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
792 wxUint32 len
, len2
, sig
, total
;
797 unsigned char sig
[4];
798 unsigned char len
[4];
807 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
809 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
812 sig
= (wxUint32
)msg
.sig
[0];
813 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
814 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
815 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
817 if (sig
!= 0xfeeddead)
819 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
823 len
= (wxUint32
)msg
.len
[0];
824 len
|= (wxUint32
)(msg
.len
[1] << 8);
825 len
|= (wxUint32
)(msg
.len
[2] << 16);
826 len
|= (wxUint32
)(msg
.len
[3] << 24);
836 // Don't attempt to read if the msg was zero bytes long.
839 total
= DoRead(buffer
, len
);
847 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
850 // NOTE: discarded bytes don't add to m_lcount.
853 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
854 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
855 len2
-= (wxUint32
)discard_len
;
857 while ((discard_len
> 0) && len2
);
859 delete [] discard_buffer
;
864 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
867 sig
= (wxUint32
)msg
.sig
[0];
868 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
869 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
870 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
872 if (sig
!= 0xdeadfeed)
874 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
890 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
895 m_lcount
= DoRead(buffer
, nbytes
);
896 Pushback(buffer
, m_lcount
);
898 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
899 if (m_flags
& wxSOCKET_WAITALL
)
900 m_error
= (m_lcount
!= nbytes
);
902 m_error
= (m_lcount
== 0);
904 // Allow read events again
910 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
915 m_lcount
= DoWrite(buffer
, nbytes
);
917 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
918 if (m_flags
& wxSOCKET_WAITALL
)
919 m_error
= (m_lcount
!= nbytes
);
921 m_error
= (m_lcount
== 0);
923 // Allow write events again
929 // This function is a mirror image of DoRead() except that it doesn't use the
930 // push back buffer, please see comments there
931 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
933 const char *buffer
= static_cast<const char *>(buffer_
);
935 // Return if there is nothing to read or the socket is (already?) closed.
936 if ( !m_impl
|| !nbytes
)
939 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
942 if ( m_flags
& wxSOCKET_NOWAIT
)
944 wxSocketUnblocker
unblock(m_impl
);
945 const int ret
= m_impl
->Write(buffer
, nbytes
);
949 else // blocking socket
953 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
956 const int ret
= m_impl
->Write(buffer
, nbytes
);
967 if ( !(m_flags
& wxSOCKET_WAITALL
) )
981 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
987 unsigned char sig
[4];
988 unsigned char len
[4];
996 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
998 msg
.sig
[0] = (unsigned char) 0xad;
999 msg
.sig
[1] = (unsigned char) 0xde;
1000 msg
.sig
[2] = (unsigned char) 0xed;
1001 msg
.sig
[3] = (unsigned char) 0xfe;
1003 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
1004 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
1005 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
1006 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
1008 if (DoWrite(&msg
, sizeof(msg
)) < sizeof(msg
))
1011 total
= DoWrite(buffer
, nbytes
);
1016 msg
.sig
[0] = (unsigned char) 0xed;
1017 msg
.sig
[1] = (unsigned char) 0xfe;
1018 msg
.sig
[2] = (unsigned char) 0xad;
1019 msg
.sig
[3] = (unsigned char) 0xde;
1023 msg
.len
[3] = (char) 0;
1025 if ((DoWrite(&msg
, sizeof(msg
))) < sizeof(msg
))
1028 // everything was OK
1039 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
1042 Pushback(buffer
, nbytes
);
1050 wxSocketBase
& wxSocketBase::Discard()
1052 char *buffer
= new char[MAX_DISCARD_SIZE
];
1059 SetFlags(wxSOCKET_NOWAIT
);
1063 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
1066 while (ret
== MAX_DISCARD_SIZE
);
1072 // Allow read events again
1078 // --------------------------------------------------------------------------
1080 // --------------------------------------------------------------------------
1083 * Polls the socket to determine its status. This function will
1084 * check for the events specified in the 'flags' parameter, and
1085 * it will return a mask indicating which operations can be
1086 * performed. This function won't block, regardless of the
1087 * mode (blocking | nonblocking) of the socket.
1089 wxSocketEventFlags
wxSocketImpl::Select(wxSocketEventFlags flags
)
1093 wxSocketEventFlags result
= 0;
1100 return (wxSOCKET_LOST_FLAG
& flags
);
1102 /* Do not use a static struct, Linux can garble it */
1106 wxFD_ZERO(&readfds
);
1107 wxFD_ZERO(&writefds
);
1108 wxFD_ZERO(&exceptfds
);
1109 wxFD_SET(m_fd
, &readfds
);
1110 if (flags
& wxSOCKET_OUTPUT_FLAG
|| flags
& wxSOCKET_CONNECTION_FLAG
)
1111 wxFD_SET(m_fd
, &writefds
);
1112 wxFD_SET(m_fd
, &exceptfds
);
1114 /* Check 'sticky' CONNECTION flag first */
1115 result
|= wxSOCKET_CONNECTION_FLAG
& m_detected
;
1117 /* If we have already detected a LOST event, then don't try
1118 * to do any further processing.
1120 if ((m_detected
& wxSOCKET_LOST_FLAG
) != 0)
1122 m_establishing
= false;
1123 return (wxSOCKET_LOST_FLAG
& flags
);
1126 /* Try select now */
1127 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
1129 /* What to do here? */
1130 return (result
& flags
);
1133 /* Check for exceptions and errors */
1134 if (wxFD_ISSET(m_fd
, &exceptfds
))
1136 m_establishing
= false;
1137 m_detected
= wxSOCKET_LOST_FLAG
;
1139 /* LOST event: Abort any further processing */
1140 return (wxSOCKET_LOST_FLAG
& flags
);
1143 /* Check for readability */
1144 if (wxFD_ISSET(m_fd
, &readfds
))
1146 result
|= wxSOCKET_INPUT_FLAG
;
1148 if (m_server
&& m_stream
)
1150 /* This is a TCP server socket that detected a connection.
1151 While the INPUT_FLAG is also set, it doesn't matter on
1152 this kind of sockets, as we can only Accept() from them. */
1153 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1157 /* Check for writability */
1158 if (wxFD_ISSET(m_fd
, &writefds
))
1160 if (m_establishing
&& !m_server
)
1163 SOCKOPTLEN_T len
= sizeof(error
);
1164 m_establishing
= false;
1165 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1169 m_detected
= wxSOCKET_LOST_FLAG
;
1171 /* LOST event: Abort any further processing */
1172 return (wxSOCKET_LOST_FLAG
& flags
);
1176 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1181 result
|= wxSOCKET_OUTPUT_FLAG
;
1185 return (result
| m_detected
) & flags
;
1188 // All Wait functions poll the socket using Select() to
1189 // check for the specified combination of conditions, until one
1190 // of these conditions become true, an error occurs, or the
1191 // timeout elapses. The polling loop runs the event loop so that
1192 // this won't block the GUI.
1195 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1197 wxCHECK_MSG( m_impl
, false, "can't wait on invalid socket" );
1199 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1200 m_interrupt
= false;
1203 // Use either the provided timeout or the default timeout value associated
1204 // with this socket.
1206 // TODO: allow waiting forever, see #9443
1207 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1208 : seconds
* 1000 + milliseconds
;
1209 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1211 // Get the active event loop which we'll use for the message dispatching
1212 // when running in the main thread
1213 wxEventLoopBase
*eventLoop
;
1214 if ( wxIsMainThread() )
1216 eventLoop
= wxEventLoop::GetActive();
1218 else // in worker thread
1220 // We never dispatch messages from threads other than the main one.
1224 // Wait in an active polling loop: notice that the loop is executed at
1225 // least once, even if timeout is 0 (i.e. polling).
1226 bool gotEvent
= false;
1229 // We always stop waiting when the connection is lost as it doesn't
1230 // make sense to continue further, even if wxSOCKET_LOST_FLAG is not
1231 // specified in flags to wait for.
1232 const wxSocketEventFlags
1233 result
= m_impl
->Select(flags
| wxSOCKET_LOST_FLAG
);
1235 // Incoming connection (server) or connection established (client)?
1236 if ( result
& wxSOCKET_CONNECTION_FLAG
)
1239 m_establishing
= false;
1244 // Data available or output buffer ready?
1245 if ( (result
& wxSOCKET_INPUT_FLAG
) || (result
& wxSOCKET_OUTPUT_FLAG
) )
1252 if ( result
& wxSOCKET_LOST_FLAG
)
1254 m_connected
= false;
1255 m_establishing
= false;
1256 if ( flags
& wxSOCKET_LOST_FLAG
)
1265 const wxMilliClock_t timeNow
= wxGetLocalTimeMillis();
1266 if ( timeNow
>= timeEnd
)
1271 // This function is only called if wxSOCKET_BLOCK flag was not used
1272 // and so we should dispatch the events if there is an event loop
1273 // capable of doing it.
1274 if ( eventLoop
->Pending() )
1275 eventLoop
->Dispatch();
1278 else // no event loop or waiting in another thread
1280 // We're busy waiting but at least give up the rest of our current
1284 #endif // wxUSE_THREADS
1290 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1292 return DoWait(seconds
, milliseconds
,
1293 wxSOCKET_INPUT_FLAG
|
1294 wxSOCKET_OUTPUT_FLAG
|
1295 wxSOCKET_CONNECTION_FLAG
|
1300 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1302 // Check pushback buffer before entering DoWait
1306 // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
1307 // because of the semantics of WaitForRead: a return value of true means
1308 // that a Read call will return immediately, not that there is
1309 // actually data to read.
1310 return DoWait(seconds
, milliseconds
, wxSOCKET_INPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1314 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1316 return DoWait(seconds
, milliseconds
, wxSOCKET_OUTPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1319 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1321 return DoWait(seconds
, milliseconds
, wxSOCKET_LOST_FLAG
);
1324 // --------------------------------------------------------------------------
1326 // --------------------------------------------------------------------------
1329 // Get local or peer address
1332 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
1339 peer
= m_impl
->GetPeer();
1341 // copying a null address would just trigger an assert anyway
1346 addr_man
.SetAddress(peer
);
1347 GAddress_destroy(peer
);
1352 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1359 local
= m_impl
->GetLocal();
1360 addr_man
.SetAddress(local
);
1361 GAddress_destroy(local
);
1367 // Save and restore socket state
1370 void wxSocketBase::SaveState()
1372 wxSocketState
*state
;
1374 state
= new wxSocketState();
1376 state
->m_flags
= m_flags
;
1377 state
->m_notify
= m_notify
;
1378 state
->m_eventmask
= m_eventmask
;
1379 state
->m_clientData
= m_clientData
;
1381 m_states
.Append(state
);
1384 void wxSocketBase::RestoreState()
1386 wxList::compatibility_iterator node
;
1387 wxSocketState
*state
;
1389 node
= m_states
.GetLast();
1393 state
= (wxSocketState
*)node
->GetData();
1395 m_flags
= state
->m_flags
;
1396 m_notify
= state
->m_notify
;
1397 m_eventmask
= state
->m_eventmask
;
1398 m_clientData
= state
->m_clientData
;
1400 m_states
.Erase(node
);
1405 // Timeout and flags
1408 void wxSocketBase::SetTimeout(long seconds
)
1410 m_timeout
= seconds
;
1413 m_impl
->SetTimeout(m_timeout
* 1000);
1416 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1418 // Do some sanity checking on the flags used: not all values can be used
1420 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1421 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1422 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1423 "wxSOCKET_NOWAIT doesn't make sense" );
1429 // --------------------------------------------------------------------------
1431 // --------------------------------------------------------------------------
1433 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1435 switch(notification
)
1437 case wxSOCKET_CONNECTION
:
1438 m_establishing
= false;
1442 // If we are in the middle of a R/W operation, do not
1443 // propagate events to users. Also, filter 'late' events
1444 // which are no longer valid.
1446 case wxSOCKET_INPUT
:
1447 if (m_reading
|| !m_impl
->Select(wxSOCKET_INPUT_FLAG
))
1451 case wxSOCKET_OUTPUT
:
1452 if (m_writing
|| !m_impl
->Select(wxSOCKET_OUTPUT_FLAG
))
1457 m_connected
= false;
1458 m_establishing
= false;
1461 case wxSOCKET_MAX_EVENT
:
1462 wxFAIL_MSG( "unexpected notification" );
1466 // Schedule the event
1468 wxSocketEventFlags flag
= 0;
1470 switch (notification
)
1472 case wxSOCKET_INPUT
: flag
= wxSOCKET_INPUT_FLAG
; break;
1473 case wxSOCKET_OUTPUT
: flag
= wxSOCKET_OUTPUT_FLAG
; break;
1474 case wxSOCKET_CONNECTION
: flag
= wxSOCKET_CONNECTION_FLAG
; break;
1475 case wxSOCKET_LOST
: flag
= wxSOCKET_LOST_FLAG
; break;
1477 wxLogWarning(_("wxSocket: unknown event!."));
1481 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1485 wxSocketEvent
event(m_id
);
1486 event
.m_event
= notification
;
1487 event
.m_clientData
= m_clientData
;
1488 event
.SetEventObject(this);
1490 m_handler
->AddPendingEvent(event
);
1495 void wxSocketBase::Notify(bool notify
)
1499 m_impl
->Notify(notify
);
1502 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1504 m_eventmask
= flags
;
1507 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1509 m_handler
= &handler
;
1513 // --------------------------------------------------------------------------
1515 // --------------------------------------------------------------------------
1517 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1521 if (m_unread
== NULL
)
1522 m_unread
= malloc(size
);
1527 tmp
= malloc(m_unrd_size
+ size
);
1528 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1534 m_unrd_size
+= size
;
1536 memcpy(m_unread
, buffer
, size
);
1539 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1541 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1546 if (size
> (m_unrd_size
-m_unrd_cur
))
1547 size
= m_unrd_size
-m_unrd_cur
;
1549 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1554 if (m_unrd_size
== m_unrd_cur
)
1567 // ==========================================================================
1569 // ==========================================================================
1571 // --------------------------------------------------------------------------
1573 // --------------------------------------------------------------------------
1575 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1576 wxSocketFlags flags
)
1577 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1579 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1581 m_impl
= wxSocketImpl::Create(*this);
1585 wxLogTrace( wxTRACE_Socket
, _T("*** Failed to create m_impl") );
1589 // Setup the socket as server
1590 m_impl
->Notify(m_notify
);
1591 m_impl
->SetLocal(addr_man
.GetAddress());
1593 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1594 m_impl
->SetReusable();
1596 if (GetFlags() & wxSOCKET_BROADCAST
) {
1597 m_impl
->SetBroadcast();
1599 if (GetFlags() & wxSOCKET_NOBIND
) {
1600 m_impl
->DontDoBind();
1603 if (m_impl
->CreateServer() != wxSOCKET_NOERROR
)
1608 wxLogTrace( wxTRACE_Socket
, _T("*** CreateServer() failed") );
1612 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_impl
->m_fd
);
1615 // --------------------------------------------------------------------------
1617 // --------------------------------------------------------------------------
1619 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1624 // If wait == false, then the call should be nonblocking.
1625 // When we are finished, we put the socket to blocking mode
1627 wxSocketUnblocker
unblock(m_impl
, !wait
);
1628 sock
.m_impl
= m_impl
->WaitConnection(sock
);
1633 sock
.m_type
= wxSOCKET_BASE
;
1634 sock
.m_connected
= true;
1639 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1641 wxSocketBase
* sock
= new wxSocketBase();
1643 sock
->SetFlags(m_flags
);
1645 if (!AcceptWith(*sock
, wait
))
1654 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1656 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
);
1659 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1661 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1663 SOCKOPTLEN_T lenreal
;
1664 if ( getsockopt(m_impl
->m_fd
, level
, optname
,
1665 static_cast<char *>(optval
), &lenreal
) != 0 )
1674 wxSocketBase::SetOption(int level
, int optname
, const void *optval
, int optlen
)
1676 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1678 return setsockopt(m_impl
->m_fd
, level
, optname
,
1679 static_cast<const char *>(optval
), optlen
) == 0;
1682 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1684 GAddress
* la
= local
.GetAddress();
1686 // If the address is valid, save it for use when we call Connect
1687 if (la
&& la
->m_addr
)
1689 m_localAddress
= local
;
1697 // ==========================================================================
1699 // ==========================================================================
1701 // --------------------------------------------------------------------------
1703 // --------------------------------------------------------------------------
1705 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1706 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1708 m_initialRecvBufferSize
=
1709 m_initialSendBufferSize
= -1;
1712 wxSocketClient::~wxSocketClient()
1716 // --------------------------------------------------------------------------
1718 // --------------------------------------------------------------------------
1720 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1721 const wxSockAddress
* local
,
1726 // Shutdown and destroy the socket
1731 m_impl
= wxSocketImpl::Create(*this);
1732 m_connected
= false;
1733 m_establishing
= false;
1738 // If wait == false, then the call should be nonblocking. When we are
1739 // finished, we put the socket to blocking mode again.
1740 wxSocketUnblocker
unblock(m_impl
, !wait
);
1742 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1743 if (GetFlags() & wxSOCKET_REUSEADDR
)
1745 m_impl
->SetReusable();
1747 if (GetFlags() & wxSOCKET_BROADCAST
)
1749 m_impl
->SetBroadcast();
1751 if (GetFlags() & wxSOCKET_NOBIND
)
1753 m_impl
->DontDoBind();
1756 // If no local address was passed and one has been set, use the one that was Set
1757 if (!local
&& m_localAddress
.GetAddress())
1759 local
= &m_localAddress
;
1762 // Bind to the local IP address and port, when provided
1765 GAddress
* la
= local
->GetAddress();
1767 if (la
&& la
->m_addr
)
1768 m_impl
->SetLocal(la
);
1771 m_impl
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1773 m_impl
->SetPeer(addr_man
.GetAddress());
1774 const wxSocketError err
= m_impl
->CreateClient();
1776 //this will register for callbacks - must be called after m_impl->m_fd was initialized
1777 m_impl
->Notify(m_notify
);
1779 if (err
!= wxSOCKET_NOERROR
)
1781 if (err
== wxSOCKET_WOULDBLOCK
)
1782 m_establishing
= true;
1791 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1793 return DoConnect(addr_man
, NULL
, wait
);
1796 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1797 const wxSockAddress
& local
,
1800 return DoConnect(addr_man
, &local
, wait
);
1803 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1807 // this happens if the initial attempt to connect succeeded without
1812 wxCHECK_MSG( m_establishing
&& m_impl
, false,
1813 "No connection establishment attempt in progress" );
1815 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1816 // true if the connection establishment process is finished, whether it is
1817 // over because we successfully connected or because we were not able to
1819 return DoWait(seconds
, milliseconds
,
1820 wxSOCKET_CONNECTION_FLAG
| wxSOCKET_LOST_FLAG
);
1823 // ==========================================================================
1825 // ==========================================================================
1827 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1828 wxSocketFlags flags
)
1829 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1831 // Create the socket
1832 m_impl
= wxSocketImpl::Create(*this);
1837 m_impl
->Notify(m_notify
);
1838 // Setup the socket as non connection oriented
1839 m_impl
->SetLocal(addr
.GetAddress());
1840 if (flags
& wxSOCKET_REUSEADDR
)
1842 m_impl
->SetReusable();
1844 if (GetFlags() & wxSOCKET_BROADCAST
)
1846 m_impl
->SetBroadcast();
1848 if (GetFlags() & wxSOCKET_NOBIND
)
1850 m_impl
->DontDoBind();
1853 if ( m_impl
->CreateUDP() != wxSOCKET_NOERROR
)
1860 // Initialize all stuff
1861 m_connected
= false;
1862 m_establishing
= false;
1865 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1874 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1878 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1880 m_impl
->SetPeer(addr
.GetAddress());
1885 // ==========================================================================
1887 // ==========================================================================
1889 class wxSocketModule
: public wxModule
1892 virtual bool OnInit()
1894 // wxSocketBase will call Initialize() itself only if sockets are
1895 // really used, don't do it from here
1899 virtual void OnExit()
1901 if ( wxSocketBase::IsInitialized() )
1902 wxSocketBase::Shutdown();
1906 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1909 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1911 #endif // wxUSE_SOCKETS