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"
53 // we use MSG_NOSIGNAL to avoid getting SIGPIPE when sending data to a remote
54 // host which closed the connection if it is available, otherwise we rely on
55 // SO_NOSIGPIPE existency
57 // this should cover all the current Unix systems (Windows never sends any
58 // signals anyhow) but if we find one that has neither we should explicitly
59 // ignore SIGPIPE for it
60 // OpenVMS has neither MSG_NOSIGNAL nor SO_NOSIGPIPE. However the socket sample
61 // seems to work. Not sure if problems will show up on OpenVMS using sockets.
63 #define wxSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
64 #else // MSG_NOSIGNAL not available (BSD including OS X)
65 #if defined(__UNIX__) && !defined(SO_NOSIGPIPE) && !defined( __VMS )
66 #error "Writing to socket could generate unhandled SIGPIPE."
67 #error "Please post information about your system to wx-dev."
70 #define wxSOCKET_MSG_NOSIGNAL 0
73 // DLL options compatibility check:
75 WX_CHECK_BUILD_OPTIONS("wxNet")
77 // --------------------------------------------------------------------------
78 // macros and constants
79 // --------------------------------------------------------------------------
82 #define MAX_DISCARD_SIZE (10 * 1024)
84 #define wxTRACE_Socket _T("wxSocket")
86 // --------------------------------------------------------------------------
88 // --------------------------------------------------------------------------
90 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
91 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
92 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
93 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
94 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
96 // ----------------------------------------------------------------------------
98 // ----------------------------------------------------------------------------
103 void SetTimeValFromMS(timeval
& tv
, unsigned long ms
)
105 tv
.tv_sec
= (ms
/ 1000);
106 tv
.tv_usec
= (ms
% 1000) * 1000;
109 } // anonymous namespace
111 // --------------------------------------------------------------------------
113 // --------------------------------------------------------------------------
115 class wxSocketState
: public wxObject
118 wxSocketFlags m_flags
;
119 wxSocketEventFlags m_eventmask
;
124 wxSocketState() : wxObject() {}
126 DECLARE_NO_COPY_CLASS(wxSocketState
)
129 // wxSocketWaitModeChanger: temporarily change the socket flags affecting its
131 class wxSocketWaitModeChanger
134 // temporarily set the flags to include the flag value which may be either
135 // wxSOCKET_NOWAIT or wxSOCKET_WAITALL
136 wxSocketWaitModeChanger(wxSocketBase
*socket
, int flag
)
138 m_oldflags(socket
->GetFlags())
141 wxASSERT_MSG( flag
== wxSOCKET_WAITALL
|| flag
== wxSOCKET_NOWAIT
,
144 // preserve wxSOCKET_BLOCK value when switching to wxSOCKET_WAITALL
145 // mode but not when switching to wxSOCKET_NOWAIT as the latter is
146 // incompatible with wxSOCKET_BLOCK
147 if ( flag
!= wxSOCKET_NOWAIT
)
148 flag
|= m_oldflags
& wxSOCKET_BLOCK
;
150 socket
->SetFlags(flag
);
153 ~wxSocketWaitModeChanger()
155 m_socket
->SetFlags(m_oldflags
);
159 wxSocketBase
* const m_socket
;
160 const int m_oldflags
;
162 DECLARE_NO_COPY_CLASS(wxSocketWaitModeChanger
)
165 // wxSocketRead/WriteGuard are instantiated before starting reading
166 // from/writing to the socket
167 class wxSocketReadGuard
170 wxSocketReadGuard(wxSocketBase
*socket
)
173 wxASSERT_MSG( !m_socket
->m_reading
, "read reentrancy?" );
175 m_socket
->m_reading
= true;
180 m_socket
->m_reading
= false;
182 m_socket
->m_impl
->ReenableEvents(wxSOCKET_INPUT_FLAG
);
186 wxSocketBase
* const m_socket
;
188 DECLARE_NO_COPY_CLASS(wxSocketReadGuard
)
191 class wxSocketWriteGuard
194 wxSocketWriteGuard(wxSocketBase
*socket
)
197 wxASSERT_MSG( !m_socket
->m_writing
, "write reentrancy?" );
199 m_socket
->m_writing
= true;
201 m_socket
->m_impl
->ReenableEvents(wxSOCKET_OUTPUT_FLAG
);
204 ~wxSocketWriteGuard()
206 m_socket
->m_writing
= false;
210 wxSocketBase
* const m_socket
;
212 DECLARE_NO_COPY_CLASS(wxSocketWriteGuard
)
215 // ============================================================================
217 // ============================================================================
219 wxSocketManager
*wxSocketManager::ms_manager
= NULL
;
222 void wxSocketManager::Set(wxSocketManager
*manager
)
224 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
226 ms_manager
= manager
;
230 void wxSocketManager::Init()
232 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
235 Details: Initialize() creates a hidden window as a sink for socket
236 events, such as 'read completed'. wxMSW has only one message loop
237 for the main thread. If Initialize is called in a secondary thread,
238 the socket window will be created for the secondary thread, but
239 since there is no message loop on this thread, it will never
240 receive events and all socket operations will time out.
241 BTW, the main thread must not be stopped using sleep or block
242 on a semaphore (a bad idea in any case) or socket operations
245 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
246 the main thread. Because secondary threads do not have run loops,
247 adding event notifications to the "Current" loop would have no
248 effect at all, events would never fire.
250 wxASSERT_MSG( wxIsMainThread(),
251 "sockets must be initialized from the main thread" );
253 wxAppConsole
* const app
= wxAppConsole::GetInstance();
254 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
256 ms_manager
= app
->GetTraits()->GetSocketManager();
259 // ==========================================================================
261 // ==========================================================================
263 wxSocketImpl::wxSocketImpl(wxSocketBase
& wxsocket
)
264 : m_wxsocket(&wxsocket
)
266 m_fd
= INVALID_SOCKET
;
267 m_error
= wxSOCKET_NOERROR
;
271 SetTimeout(wxsocket
.GetTimeout() * 1000);
273 m_establishing
= false;
277 m_initialRecvBufferSize
= -1;
278 m_initialSendBufferSize
= -1;
281 wxSocketImpl::~wxSocketImpl()
283 if ( m_fd
!= INVALID_SOCKET
)
287 bool wxSocketImpl::PreCreateCheck(const wxSockAddressImpl
& addr
)
289 if ( m_fd
!= INVALID_SOCKET
)
291 m_error
= wxSOCKET_INVSOCK
;
297 m_error
= wxSOCKET_INVADDR
;
304 void wxSocketImpl::PostCreation()
306 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
308 EnableSocketOption(SO_NOSIGPIPE
);
312 EnableSocketOption(SO_REUSEADDR
);
316 wxASSERT_MSG( !m_stream
, "broadcasting is for datagram sockets only" );
318 EnableSocketOption(SO_BROADCAST
);
321 if ( m_initialRecvBufferSize
>= 0 )
322 SetSocketOption(SO_RCVBUF
, m_initialRecvBufferSize
);
323 if ( m_initialSendBufferSize
>= 0 )
324 SetSocketOption(SO_SNDBUF
, m_initialSendBufferSize
);
326 // we always put our sockets in unblocked mode and handle blocking
327 // ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
328 UnblockAndRegisterWithEventLoop();
331 wxSocketError
wxSocketImpl::UpdateLocalAddress()
333 WX_SOCKLEN_T lenAddr
= m_local
.GetLen();
334 if ( getsockname(m_fd
, m_local
.GetWritableAddr(), &lenAddr
) != 0 )
337 m_error
= wxSOCKET_IOERR
;
341 return wxSOCKET_NOERROR
;
344 wxSocketError
wxSocketImpl::CreateServer()
346 if ( !PreCreateCheck(m_local
) )
352 // do create the socket
353 m_fd
= socket(m_local
.GetFamily(), SOCK_STREAM
, 0);
355 if ( m_fd
== INVALID_SOCKET
)
357 m_error
= wxSOCKET_IOERR
;
358 return wxSOCKET_IOERR
;
363 // and then bind to and listen on it
365 // FIXME: should we test for m_dobind here?
366 if ( bind(m_fd
, m_local
.GetAddr(), m_local
.GetLen()) != 0 )
367 m_error
= wxSOCKET_IOERR
;
371 if ( listen(m_fd
, 5) != 0 )
372 m_error
= wxSOCKET_IOERR
;
381 // finally retrieve the address we effectively bound to
382 return UpdateLocalAddress();
385 wxSocketError
wxSocketImpl::CreateClient(bool wait
)
387 if ( !PreCreateCheck(m_peer
) )
390 m_fd
= socket(m_peer
.GetFamily(), SOCK_STREAM
, 0);
392 if ( m_fd
== INVALID_SOCKET
)
394 m_error
= wxSOCKET_IOERR
;
395 return wxSOCKET_IOERR
;
400 // If a local address has been set, then bind to it before calling connect
401 if ( m_local
.IsOk() )
403 if ( bind(m_fd
, m_local
.GetAddr(), m_local
.GetLen()) != 0 )
406 m_error
= wxSOCKET_IOERR
;
412 int rc
= connect(m_fd
, m_peer
.GetAddr(), m_peer
.GetLen());
413 if ( rc
== SOCKET_ERROR
)
415 wxSocketError err
= GetLastError();
416 if ( err
== wxSOCKET_WOULDBLOCK
)
418 m_establishing
= true;
420 // block waiting for connection if we should (otherwise just return
421 // wxSOCKET_WOULDBLOCK to the caller)
424 err
= SelectWithTimeout(wxSOCKET_CONNECTION_FLAG
)
427 m_establishing
= false;
435 m_error
= wxSOCKET_NOERROR
;
442 wxSocketError
wxSocketImpl::CreateUDP()
444 if ( !PreCreateCheck(m_local
) )
450 m_fd
= socket(m_local
.GetFamily(), SOCK_DGRAM
, 0);
452 if ( m_fd
== INVALID_SOCKET
)
454 m_error
= wxSOCKET_IOERR
;
455 return wxSOCKET_IOERR
;
462 if ( bind(m_fd
, m_local
.GetAddr(), m_local
.GetLen()) != 0 )
465 m_error
= wxSOCKET_IOERR
;
469 return UpdateLocalAddress();
472 return wxSOCKET_NOERROR
;
475 wxSocketImpl
*wxSocketImpl::Accept(wxSocketBase
& wxsocket
)
477 wxSockAddressStorage from
;
478 WX_SOCKLEN_T fromlen
= sizeof(from
);
479 const SOCKET fd
= accept(m_fd
, &from
.addr
, &fromlen
);
481 // accepting is similar to reading in the sense that it resets "ready for
482 // read" flag on the socket
483 ReenableEvents(wxSOCKET_INPUT_FLAG
);
485 if ( fd
== INVALID_SOCKET
)
488 wxSocketImpl
* const sock
= Create(wxsocket
);
490 sock
->m_peer
= wxSockAddressImpl(from
.addr
, fromlen
);
492 sock
->UnblockAndRegisterWithEventLoop();
498 void wxSocketImpl::Close()
500 if ( m_fd
!= INVALID_SOCKET
)
503 m_fd
= INVALID_SOCKET
;
507 void wxSocketImpl::Shutdown()
509 if ( m_fd
!= INVALID_SOCKET
)
511 shutdown(m_fd
, 1 /* SD_SEND */);
517 * Sets the timeout for blocking calls. Time is expressed in
520 void wxSocketImpl::SetTimeout(unsigned long millis
)
522 SetTimeValFromMS(m_timeout
, millis
);
525 void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event
)
527 m_wxsocket
->OnRequest(event
);
530 /* Address handling */
531 wxSocketError
wxSocketImpl::SetLocal(const wxSockAddressImpl
& local
)
533 /* the socket must be initialized, or it must be a server */
534 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
536 m_error
= wxSOCKET_INVSOCK
;
537 return wxSOCKET_INVSOCK
;
542 m_error
= wxSOCKET_INVADDR
;
543 return wxSOCKET_INVADDR
;
548 return wxSOCKET_NOERROR
;
551 wxSocketError
wxSocketImpl::SetPeer(const wxSockAddressImpl
& peer
)
555 m_error
= wxSOCKET_INVADDR
;
556 return wxSOCKET_INVADDR
;
561 return wxSOCKET_NOERROR
;
564 const wxSockAddressImpl
& wxSocketImpl::GetLocal()
566 if ( !m_local
.IsOk() )
567 UpdateLocalAddress();
572 // ----------------------------------------------------------------------------
574 // ----------------------------------------------------------------------------
576 // this macro wraps the given expression (normally a syscall) in a loop which
577 // ignores any interruptions, i.e. reevaluates it again if it failed and errno
580 #define DO_WHILE_EINTR( rc, syscall ) \
584 while ( rc == -1 && errno == EINTR )
586 #define DO_WHILE_EINTR( rc, syscall ) rc = (syscall)
589 int wxSocketImpl::RecvStream(void *buffer
, int size
)
592 DO_WHILE_EINTR( ret
, recv(m_fd
, static_cast<char *>(buffer
), size
, 0) );
596 // receiving 0 bytes for a TCP socket indicates that the connection was
597 // closed by peer so shut down our end as well (for UDP sockets empty
598 // datagrams are also possible)
599 m_establishing
= false;
600 NotifyOnStateChange(wxSOCKET_LOST
);
604 // do not return an error in this case however
610 int wxSocketImpl::SendStream(const void *buffer
, int size
)
613 DO_WHILE_EINTR( ret
, send(m_fd
, static_cast<const char *>(buffer
), size
,
614 wxSOCKET_MSG_NOSIGNAL
) );
619 int wxSocketImpl::RecvDgram(void *buffer
, int size
)
621 wxSockAddressStorage from
;
622 WX_SOCKLEN_T fromlen
= sizeof(from
);
625 DO_WHILE_EINTR( ret
, recvfrom(m_fd
, static_cast<char *>(buffer
), size
,
626 0, &from
.addr
, &fromlen
) );
628 if ( ret
== SOCKET_ERROR
)
631 m_peer
= wxSockAddressImpl(from
.addr
, fromlen
);
632 if ( !m_peer
.IsOk() )
638 int wxSocketImpl::SendDgram(const void *buffer
, int size
)
640 if ( !m_peer
.IsOk() )
642 m_error
= wxSOCKET_INVADDR
;
647 DO_WHILE_EINTR( ret
, sendto(m_fd
, static_cast<const char *>(buffer
), size
,
648 0, m_peer
.GetAddr(), m_peer
.GetLen()) );
653 int wxSocketImpl::Read(void *buffer
, int size
)
655 // server sockets can't be used for IO, only to accept new connections
656 if ( m_fd
== INVALID_SOCKET
|| m_server
)
658 m_error
= wxSOCKET_INVSOCK
;
662 int ret
= m_stream
? RecvStream(buffer
, size
)
663 : RecvDgram(buffer
, size
);
665 m_error
= ret
== SOCKET_ERROR
? GetLastError() : wxSOCKET_NOERROR
;
670 int wxSocketImpl::Write(const void *buffer
, int size
)
672 if ( m_fd
== INVALID_SOCKET
|| m_server
)
674 m_error
= wxSOCKET_INVSOCK
;
678 int ret
= m_stream
? SendStream(buffer
, size
)
679 : SendDgram(buffer
, size
);
681 m_error
= ret
== SOCKET_ERROR
? GetLastError() : wxSOCKET_NOERROR
;
686 // ==========================================================================
688 // ==========================================================================
690 // --------------------------------------------------------------------------
691 // Initialization and shutdown
692 // --------------------------------------------------------------------------
694 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
695 // to m_countInit with a crit section
696 size_t wxSocketBase::m_countInit
= 0;
698 bool wxSocketBase::IsInitialized()
700 return m_countInit
> 0;
703 bool wxSocketBase::Initialize()
705 if ( !m_countInit
++ )
707 wxSocketManager
* const manager
= wxSocketManager::Get();
708 if ( !manager
|| !manager
->OnInit() )
719 void wxSocketBase::Shutdown()
721 // we should be initialized
722 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
723 if ( --m_countInit
== 0 )
725 wxSocketManager
* const manager
= wxSocketManager::Get();
726 wxCHECK_RET( manager
, "should have a socket manager" );
732 // --------------------------------------------------------------------------
734 // --------------------------------------------------------------------------
736 void wxSocketBase::Init()
739 m_type
= wxSOCKET_UNINIT
;
750 m_beingDeleted
= false;
765 if ( !IsInitialized() )
767 // this Initialize() will be undone by wxSocketModule::OnExit(), all
768 // the other calls to it should be matched by a call to Shutdown()
773 wxSocketBase::wxSocketBase()
778 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
787 wxSocketBase::~wxSocketBase()
789 // Just in case the app called Destroy() *and* then deleted the socket
790 // immediately: don't leave dangling pointers.
791 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
793 traits
->RemoveFromPendingDelete(this);
795 // Shutdown and close the socket
799 // Destroy the implementation object
802 // Free the pushback buffer
807 bool wxSocketBase::Destroy()
809 // Delayed destruction: the socket will be deleted during the next idle
810 // loop iteration. This ensures that all pending events have been
812 m_beingDeleted
= true;
814 // Shutdown and close the socket
817 // Suppress events from now on
820 // schedule this object for deletion
821 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
824 // let the traits object decide what to do with us
825 traits
->ScheduleForDestroy(this);
827 else // no app or no traits
829 // in wxBase we might have no app object at all, don't leak memory
836 // ----------------------------------------------------------------------------
838 // ----------------------------------------------------------------------------
840 void wxSocketBase::SetError(wxSocketError error
)
842 m_impl
->m_error
= error
;
845 wxSocketError
wxSocketBase::LastError() const
847 return m_impl
->GetError();
850 // --------------------------------------------------------------------------
852 // --------------------------------------------------------------------------
854 // The following IO operations update m_lcount:
855 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
856 bool wxSocketBase::Close()
858 // Interrupt pending waits
864 m_establishing
= false;
868 void wxSocketBase::ShutdownOutput()
874 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
876 wxSocketReadGuard
read(this);
878 m_lcount
= DoRead(buffer
, nbytes
);
883 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
885 wxCHECK_MSG( m_impl
, 0, "socket must be valid" );
887 // We use pointer arithmetic here which doesn't work with void pointers.
888 char *buffer
= static_cast<char *>(buffer_
);
889 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
891 // Try the push back buffer first, even before checking whether the socket
892 // is valid to allow reading previously pushed back data from an already
894 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
900 // our socket is non-blocking so Read() will return immediately if
901 // there is nothing to read yet and it's more efficient to try it first
902 // before entering DoWait() which is going to start dispatching GUI
903 // events and, even more importantly, we must do this under Windows
904 // where we're not going to get notifications about socket being ready
905 // for reading before we read all the existing data from it
906 const int ret
= m_connected
? m_impl
->Read(buffer
, nbytes
) : 0;
909 if ( m_impl
->GetLastError() == wxSOCKET_WOULDBLOCK
)
911 // if we don't want to wait, just return immediately
912 if ( m_flags
& wxSOCKET_NOWAIT
)
915 // otherwise wait until the socket becomes ready for reading or
916 // an error occurs on it
917 if ( !DoWaitWithTimeout(wxSOCKET_INPUT_FLAG
) )
919 // and exit if the timeout elapsed before it did
920 SetError(wxSOCKET_TIMEDOUT
);
929 SetError(wxSOCKET_IOERR
);
935 // for connection-oriented (e.g. TCP) sockets we can only read
936 // 0 bytes if the other end has been closed, and for connectionless
937 // ones (UDP) this flag doesn't make sense anyhow so we can set it
938 // to true too without doing any harm
941 // we're not going to read anything else and so if we haven't read
942 // anything (or not everything in wxSOCKET_WAITALL case) already,
944 if ( (m_flags
& wxSOCKET_WAITALL
) || !total
)
945 SetError(wxSOCKET_IOERR
);
951 // if we are happy to read something and not the entire nbytes bytes,
953 if ( !(m_flags
& wxSOCKET_WAITALL
) )
963 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
967 unsigned char sig
[4];
968 unsigned char len
[4];
971 wxSocketReadGuard
read(this);
973 wxSocketWaitModeChanger
changeFlags(this, wxSOCKET_WAITALL
);
976 if ( DoRead(&msg
, sizeof(msg
)) == sizeof(msg
) )
978 wxUint32 sig
= (wxUint32
)msg
.sig
[0];
979 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
980 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
981 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
983 if ( sig
== 0xfeeddead )
985 wxUint32 len
= (wxUint32
)msg
.len
[0];
986 len
|= (wxUint32
)(msg
.len
[1] << 8);
987 len
|= (wxUint32
)(msg
.len
[2] << 16);
988 len
|= (wxUint32
)(msg
.len
[3] << 24);
999 // Don't attempt to read if the msg was zero bytes long.
1000 m_lcount
= len
? DoRead(buffer
, len
) : 0;
1004 char discard_buffer
[MAX_DISCARD_SIZE
];
1007 // NOTE: discarded bytes don't add to m_lcount.
1010 discard_len
= len2
> MAX_DISCARD_SIZE
1013 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
1014 len2
-= (wxUint32
)discard_len
;
1016 while ((discard_len
> 0) && len2
);
1019 if ( !len2
&& DoRead(&msg
, sizeof(msg
)) == sizeof(msg
) )
1021 sig
= (wxUint32
)msg
.sig
[0];
1022 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
1023 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
1024 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
1026 if ( sig
== 0xdeadfeed )
1033 SetError(wxSOCKET_IOERR
);
1038 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
1040 wxSocketReadGuard
read(this);
1042 m_lcount
= DoRead(buffer
, nbytes
);
1044 Pushback(buffer
, m_lcount
);
1049 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
1051 wxSocketWriteGuard
write(this);
1053 m_lcount
= DoWrite(buffer
, nbytes
);
1058 // This function is a mirror image of DoRead() except that it doesn't use the
1059 // push back buffer and doesn't treat 0 return value specially (normally this
1060 // shouldn't happen at all here), so please see comments there for explanations
1061 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
1063 wxCHECK_MSG( m_impl
, 0, "socket must be valid" );
1065 const char *buffer
= static_cast<const char *>(buffer_
);
1066 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1073 if ( (m_flags
& wxSOCKET_WAITALL
) || !total
)
1074 SetError(wxSOCKET_IOERR
);
1078 const int ret
= m_impl
->Write(buffer
, nbytes
);
1081 if ( m_impl
->GetLastError() == wxSOCKET_WOULDBLOCK
)
1083 if ( m_flags
& wxSOCKET_NOWAIT
)
1086 if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG
) )
1088 SetError(wxSOCKET_TIMEDOUT
);
1094 else // "real" error
1096 SetError(wxSOCKET_IOERR
);
1103 if ( !(m_flags
& wxSOCKET_WAITALL
) )
1113 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
1117 unsigned char sig
[4];
1118 unsigned char len
[4];
1121 wxSocketWriteGuard
write(this);
1123 wxSocketWaitModeChanger
changeFlags(this, wxSOCKET_WAITALL
);
1125 msg
.sig
[0] = (unsigned char) 0xad;
1126 msg
.sig
[1] = (unsigned char) 0xde;
1127 msg
.sig
[2] = (unsigned char) 0xed;
1128 msg
.sig
[3] = (unsigned char) 0xfe;
1130 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
1131 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
1132 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
1133 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
1136 if ( DoWrite(&msg
, sizeof(msg
)) == sizeof(msg
) )
1138 m_lcount
= DoWrite(buffer
, nbytes
);
1139 if ( m_lcount
== nbytes
)
1141 msg
.sig
[0] = (unsigned char) 0xed;
1142 msg
.sig
[1] = (unsigned char) 0xfe;
1143 msg
.sig
[2] = (unsigned char) 0xad;
1144 msg
.sig
[3] = (unsigned char) 0xde;
1148 msg
.len
[3] = (char) 0;
1150 if ( DoWrite(&msg
, sizeof(msg
)) == sizeof(msg
))
1156 SetError(wxSOCKET_IOERR
);
1161 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
1164 Pushback(buffer
, nbytes
);
1166 SetError(wxSOCKET_NOERROR
);
1172 wxSocketBase
& wxSocketBase::Discard()
1174 char *buffer
= new char[MAX_DISCARD_SIZE
];
1178 wxSocketReadGuard
read(this);
1180 wxSocketWaitModeChanger
changeFlags(this, wxSOCKET_NOWAIT
);
1184 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
1187 while (ret
== MAX_DISCARD_SIZE
);
1191 SetError(wxSOCKET_NOERROR
);
1196 // --------------------------------------------------------------------------
1198 // --------------------------------------------------------------------------
1201 This function will check for the events specified in the flags parameter,
1202 and it will return a mask indicating which operations can be performed.
1204 wxSocketEventFlags
wxSocketImpl::Select(wxSocketEventFlags flags
,
1205 const timeval
*timeout
)
1207 if ( m_fd
== INVALID_SOCKET
)
1208 return (wxSOCKET_LOST_FLAG
& flags
);
1214 tv
.tv_sec
= tv
.tv_usec
= 0;
1216 // prepare the FD sets, passing NULL for the one(s) we don't use
1218 readfds
, *preadfds
= NULL
,
1219 writefds
, *pwritefds
= NULL
,
1220 exceptfds
; // always want to know about errors
1222 if ( flags
& wxSOCKET_INPUT_FLAG
)
1224 preadfds
= &readfds
;
1225 wxFD_ZERO(preadfds
);
1226 wxFD_SET(m_fd
, preadfds
);
1229 // when using non-blocking connect() the socket becomes connected
1230 // (successfully or not) when it becomes writable
1231 if ( flags
& (wxSOCKET_OUTPUT_FLAG
| wxSOCKET_CONNECTION_FLAG
) )
1233 pwritefds
= &writefds
;
1234 wxFD_ZERO(pwritefds
);
1235 wxFD_SET(m_fd
, pwritefds
);
1238 wxFD_ZERO(&exceptfds
);
1239 wxFD_SET(m_fd
, &exceptfds
);
1241 const int rc
= select(m_fd
+ 1, preadfds
, pwritefds
, &exceptfds
, &tv
);
1243 // check for errors first
1244 if ( rc
== -1 || wxFD_ISSET(m_fd
, &exceptfds
) )
1246 m_establishing
= false;
1248 return wxSOCKET_LOST_FLAG
& flags
;
1254 wxASSERT_MSG( rc
== 1, "unexpected select() return value" );
1256 wxSocketEventFlags detected
= 0;
1257 if ( preadfds
&& wxFD_ISSET(m_fd
, preadfds
) )
1258 detected
|= wxSOCKET_INPUT_FLAG
;
1260 if ( pwritefds
&& wxFD_ISSET(m_fd
, pwritefds
) )
1262 // check for the case of non-blocking connect()
1263 if ( m_establishing
&& !m_server
)
1266 SOCKOPTLEN_T len
= sizeof(error
);
1267 m_establishing
= false;
1268 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1271 detected
= wxSOCKET_LOST_FLAG
;
1273 detected
|= wxSOCKET_CONNECTION_FLAG
;
1275 else // not called to get non-blocking connect() status
1277 detected
|= wxSOCKET_OUTPUT_FLAG
;
1281 return detected
& flags
;
1285 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1287 // Use either the provided timeout or the default timeout value associated
1288 // with this socket.
1290 // TODO: allow waiting forever, see #9443
1291 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1292 : seconds
* 1000 + milliseconds
;
1294 return DoWait(timeout
, flags
);
1298 wxSocketBase::DoWait(long timeout
, wxSocketEventFlags flags
)
1300 wxCHECK_MSG( m_impl
, -1, "can't wait on invalid socket" );
1302 // we're never going to become ready if we're not connected (any more)
1303 if ( !m_connected
&& !m_establishing
)
1306 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1307 m_interrupt
= false;
1310 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1312 // Get the active event loop which we'll use for the message dispatching
1313 // when running in the main thread unless this was explicitly disabled by
1314 // setting wxSOCKET_BLOCK flag
1315 wxEventLoopBase
*eventLoop
;
1316 if ( !(m_flags
& wxSOCKET_BLOCK
) && wxIsMainThread() )
1318 eventLoop
= wxEventLoop::GetActive();
1320 else // in worker thread
1322 // We never dispatch messages from threads other than the main one.
1326 // Wait until we receive the event we're waiting for or the timeout expires
1327 // (but note that we always execute the loop at least once, even if timeout
1328 // is 0 as this is used for polling)
1330 for ( bool firstTime
= true; !m_interrupt
; firstTime
= false )
1332 long timeLeft
= wxMilliClockToLong(timeEnd
- wxGetLocalTimeMillis());
1341 wxSocketEventFlags events
;
1344 // reset them before starting to wait
1347 eventLoop
->DispatchTimeout(timeLeft
);
1349 events
= m_eventsgot
;
1351 else // no event loop or waiting in another thread
1353 // as explained below, we should always check for wxSOCKET_LOST_FLAG
1355 SetTimeValFromMS(tv
, timeLeft
);
1356 events
= m_impl
->Select(flags
| wxSOCKET_LOST_FLAG
, &tv
);
1359 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1360 // it, as continuing to wait for anything else after getting it is
1362 if ( events
& wxSOCKET_LOST_FLAG
)
1364 m_connected
= false;
1365 m_establishing
= false;
1370 // otherwise mask out the bits we're not interested in
1373 // Incoming connection (server) or connection established (client)?
1374 if ( events
& wxSOCKET_CONNECTION_FLAG
)
1377 m_establishing
= false;
1382 // Data available or output buffer ready?
1383 if ( (events
& wxSOCKET_INPUT_FLAG
) || (events
& wxSOCKET_OUTPUT_FLAG
) )
1393 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1395 return DoWait(seconds
, milliseconds
,
1396 wxSOCKET_INPUT_FLAG
|
1397 wxSOCKET_OUTPUT_FLAG
|
1398 wxSOCKET_CONNECTION_FLAG
) != 0;
1401 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1403 // Check pushback buffer before entering DoWait
1407 // Check if the socket is not already ready for input, if it is, there is
1408 // no need to start waiting for it (worse, we'll actually never get a
1409 // notification about the socket becoming ready if it is already under
1411 if ( m_impl
->Select(wxSOCKET_INPUT_FLAG
) )
1414 return DoWait(seconds
, milliseconds
, wxSOCKET_INPUT_FLAG
) != 0;
1418 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1420 if ( m_impl
->Select(wxSOCKET_OUTPUT_FLAG
) )
1423 return DoWait(seconds
, milliseconds
, wxSOCKET_OUTPUT_FLAG
) != 0;
1426 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1428 return DoWait(seconds
, milliseconds
, wxSOCKET_LOST_FLAG
) == -1;
1431 // --------------------------------------------------------------------------
1433 // --------------------------------------------------------------------------
1436 // Get local or peer address
1439 bool wxSocketBase::GetPeer(wxSockAddress
& addr
) const
1441 wxCHECK_MSG( m_impl
, false, "invalid socket" );
1443 const wxSockAddressImpl
& peer
= m_impl
->GetPeer();
1447 addr
.SetAddress(peer
);
1452 bool wxSocketBase::GetLocal(wxSockAddress
& addr
) const
1454 wxCHECK_MSG( m_impl
, false, "invalid socket" );
1456 const wxSockAddressImpl
& local
= m_impl
->GetLocal();
1457 if ( !local
.IsOk() )
1460 addr
.SetAddress(local
);
1466 // Save and restore socket state
1469 void wxSocketBase::SaveState()
1471 wxSocketState
*state
;
1473 state
= new wxSocketState();
1475 state
->m_flags
= m_flags
;
1476 state
->m_notify
= m_notify
;
1477 state
->m_eventmask
= m_eventmask
;
1478 state
->m_clientData
= m_clientData
;
1480 m_states
.Append(state
);
1483 void wxSocketBase::RestoreState()
1485 wxList::compatibility_iterator node
;
1486 wxSocketState
*state
;
1488 node
= m_states
.GetLast();
1492 state
= (wxSocketState
*)node
->GetData();
1494 m_flags
= state
->m_flags
;
1495 m_notify
= state
->m_notify
;
1496 m_eventmask
= state
->m_eventmask
;
1497 m_clientData
= state
->m_clientData
;
1499 m_states
.Erase(node
);
1504 // Timeout and flags
1507 void wxSocketBase::SetTimeout(long seconds
)
1509 m_timeout
= seconds
;
1512 m_impl
->SetTimeout(m_timeout
* 1000);
1515 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1517 // Do some sanity checking on the flags used: not all values can be used
1519 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1520 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1521 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1522 "wxSOCKET_NOWAIT doesn't make sense" );
1528 // --------------------------------------------------------------------------
1530 // --------------------------------------------------------------------------
1532 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1534 wxSocketEventFlags flag
= 0;
1535 switch ( notification
)
1537 case wxSOCKET_INPUT
:
1538 flag
= wxSOCKET_INPUT_FLAG
;
1541 case wxSOCKET_OUTPUT
:
1542 flag
= wxSOCKET_OUTPUT_FLAG
;
1545 case wxSOCKET_CONNECTION
:
1546 flag
= wxSOCKET_CONNECTION_FLAG
;
1550 flag
= wxSOCKET_LOST_FLAG
;
1554 wxFAIL_MSG( "unknown wxSocket notification" );
1557 // if we lost the connection the socket is now closed
1558 if ( notification
== wxSOCKET_LOST
)
1561 // remember the events which were generated for this socket, we're going to
1562 // use this in DoWait()
1563 m_eventsgot
|= flag
;
1565 // send the wx event if enabled and we're interested in it
1566 if ( m_notify
&& (m_eventmask
& flag
) && m_handler
)
1568 // don't generate the events when we're inside DoWait() called from our
1569 // own code as we are going to consume the data that has just become
1570 // available ourselves and the user code won't see it at all
1571 if ( (notification
== wxSOCKET_INPUT
&& m_reading
) ||
1572 (notification
== wxSOCKET_OUTPUT
&& m_writing
) )
1577 wxSocketEvent
event(m_id
);
1578 event
.m_event
= notification
;
1579 event
.m_clientData
= m_clientData
;
1580 event
.SetEventObject(this);
1582 m_handler
->AddPendingEvent(event
);
1586 void wxSocketBase::Notify(bool notify
)
1591 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1593 m_eventmask
= flags
;
1596 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1598 m_handler
= &handler
;
1602 // --------------------------------------------------------------------------
1604 // --------------------------------------------------------------------------
1606 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1610 if (m_unread
== NULL
)
1611 m_unread
= malloc(size
);
1616 tmp
= malloc(m_unrd_size
+ size
);
1617 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1623 m_unrd_size
+= size
;
1625 memcpy(m_unread
, buffer
, size
);
1628 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1630 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1635 if (size
> (m_unrd_size
-m_unrd_cur
))
1636 size
= m_unrd_size
-m_unrd_cur
;
1638 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1643 if (m_unrd_size
== m_unrd_cur
)
1656 // ==========================================================================
1658 // ==========================================================================
1660 // --------------------------------------------------------------------------
1662 // --------------------------------------------------------------------------
1664 wxSocketServer::wxSocketServer(const wxSockAddress
& addr
,
1665 wxSocketFlags flags
)
1666 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1668 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1670 m_impl
= wxSocketImpl::Create(*this);
1674 wxLogTrace( wxTRACE_Socket
, _T("*** Failed to create m_impl") );
1678 // Setup the socket as server
1679 m_impl
->SetLocal(addr
.GetAddress());
1681 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1682 m_impl
->SetReusable();
1684 if (GetFlags() & wxSOCKET_BROADCAST
) {
1685 m_impl
->SetBroadcast();
1687 if (GetFlags() & wxSOCKET_NOBIND
) {
1688 m_impl
->DontDoBind();
1691 if (m_impl
->CreateServer() != wxSOCKET_NOERROR
)
1696 wxLogTrace( wxTRACE_Socket
, _T("*** CreateServer() failed") );
1700 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_impl
->m_fd
);
1703 // --------------------------------------------------------------------------
1705 // --------------------------------------------------------------------------
1707 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1709 if ( !m_impl
|| (m_impl
->m_fd
== INVALID_SOCKET
) || !m_impl
->IsServer() )
1711 wxFAIL_MSG( "can only be called for a valid server socket" );
1713 SetError(wxSOCKET_INVSOCK
);
1720 // wait until we get a connection
1721 if ( !m_impl
->SelectWithTimeout(wxSOCKET_INPUT_FLAG
) )
1723 SetError(wxSOCKET_TIMEDOUT
);
1729 sock
.m_impl
= m_impl
->Accept(sock
);
1733 SetError(m_impl
->GetLastError());
1738 sock
.m_type
= wxSOCKET_BASE
;
1739 sock
.m_connected
= true;
1744 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1746 wxSocketBase
* sock
= new wxSocketBase();
1748 sock
->SetFlags(m_flags
);
1750 if (!AcceptWith(*sock
, wait
))
1759 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1761 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
) == 1;
1764 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1766 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1768 SOCKOPTLEN_T lenreal
= *optlen
;
1769 if ( getsockopt(m_impl
->m_fd
, level
, optname
,
1770 static_cast<char *>(optval
), &lenreal
) != 0 )
1779 wxSocketBase::SetOption(int level
, int optname
, const void *optval
, int optlen
)
1781 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1783 return setsockopt(m_impl
->m_fd
, level
, optname
,
1784 static_cast<const char *>(optval
), optlen
) == 0;
1787 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1789 m_localAddress
= local
;
1794 // ==========================================================================
1796 // ==========================================================================
1798 // --------------------------------------------------------------------------
1800 // --------------------------------------------------------------------------
1802 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1803 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1805 m_initialRecvBufferSize
=
1806 m_initialSendBufferSize
= -1;
1809 // --------------------------------------------------------------------------
1811 // --------------------------------------------------------------------------
1813 bool wxSocketClient::DoConnect(const wxSockAddress
& remote
,
1814 const wxSockAddress
* local
,
1819 // Shutdown and destroy the old socket
1824 m_connected
= false;
1825 m_establishing
= false;
1827 // Create and set up the new one
1828 m_impl
= wxSocketImpl::Create(*this);
1832 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1833 if (GetFlags() & wxSOCKET_REUSEADDR
)
1834 m_impl
->SetReusable();
1835 if (GetFlags() & wxSOCKET_BROADCAST
)
1836 m_impl
->SetBroadcast();
1837 if (GetFlags() & wxSOCKET_NOBIND
)
1838 m_impl
->DontDoBind();
1840 // Bind to the local IP address and port, when provided or if one had been
1842 if ( !local
&& m_localAddress
.GetAddress().IsOk() )
1843 local
= &m_localAddress
;
1846 m_impl
->SetLocal(local
->GetAddress());
1848 m_impl
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1850 m_impl
->SetPeer(remote
.GetAddress());
1852 // Finally do create the socket and connect to the peer
1853 const wxSocketError err
= m_impl
->CreateClient(wait
);
1855 if ( err
!= wxSOCKET_NOERROR
)
1857 if ( err
== wxSOCKET_WOULDBLOCK
)
1859 wxASSERT_MSG( !wait
, "shouldn't get this for blocking connect" );
1861 m_establishing
= true;
1871 bool wxSocketClient::Connect(const wxSockAddress
& remote
, bool wait
)
1873 return DoConnect(remote
, NULL
, wait
);
1876 bool wxSocketClient::Connect(const wxSockAddress
& remote
,
1877 const wxSockAddress
& local
,
1880 return DoConnect(remote
, &local
, wait
);
1883 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1887 // this happens if the initial attempt to connect succeeded without
1892 wxCHECK_MSG( m_establishing
&& m_impl
, false,
1893 "No connection establishment attempt in progress" );
1895 // notice that we return true even if DoWait() returned -1, i.e. if an
1896 // error occurred and connection was lost: this is intentional as we should
1897 // return false only if timeout expired without anything happening
1898 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
) != 0;
1901 // ==========================================================================
1903 // ==========================================================================
1905 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1906 wxSocketFlags flags
)
1907 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1909 // Create the socket
1910 m_impl
= wxSocketImpl::Create(*this);
1915 // Setup the socket as non connection oriented
1916 m_impl
->SetLocal(addr
.GetAddress());
1917 if (flags
& wxSOCKET_REUSEADDR
)
1919 m_impl
->SetReusable();
1921 if (GetFlags() & wxSOCKET_BROADCAST
)
1923 m_impl
->SetBroadcast();
1925 if (GetFlags() & wxSOCKET_NOBIND
)
1927 m_impl
->DontDoBind();
1930 if ( m_impl
->CreateUDP() != wxSOCKET_NOERROR
)
1937 // Initialize all stuff
1938 m_connected
= false;
1939 m_establishing
= false;
1942 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1951 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1955 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1957 m_impl
->SetPeer(addr
.GetAddress());
1962 // ==========================================================================
1964 // ==========================================================================
1966 class wxSocketModule
: public wxModule
1969 virtual bool OnInit()
1971 // wxSocketBase will call Initialize() itself only if sockets are
1972 // really used, don't do it from here
1976 virtual void OnExit()
1978 if ( wxSocketBase::IsInitialized() )
1979 wxSocketBase::Shutdown();
1983 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1986 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1988 #endif // wxUSE_SOCKETS