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
61 #define wxSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
62 #else // MSG_NOSIGNAL not available (BSD including OS X)
63 #if defined(__UNIX__) && !defined(SO_NOSIGPIPE)
64 #error "Writing to socket could generate unhandled SIGPIPE."
65 #error "Please post information about your system to wx-dev."
68 #define wxSOCKET_MSG_NOSIGNAL 0
71 // DLL options compatibility check:
73 WX_CHECK_BUILD_OPTIONS("wxNet")
75 // --------------------------------------------------------------------------
76 // macros and constants
77 // --------------------------------------------------------------------------
80 #define MAX_DISCARD_SIZE (10 * 1024)
82 #define wxTRACE_Socket _T("wxSocket")
84 // --------------------------------------------------------------------------
86 // --------------------------------------------------------------------------
88 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
89 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
90 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
91 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
92 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
94 // ----------------------------------------------------------------------------
96 // ----------------------------------------------------------------------------
101 void SetTimeValFromMS(timeval
& tv
, unsigned long ms
)
103 tv
.tv_sec
= (ms
/ 1000);
104 tv
.tv_usec
= (ms
% 1000) * 1000;
107 } // anonymous namespace
109 // --------------------------------------------------------------------------
111 // --------------------------------------------------------------------------
113 class wxSocketState
: public wxObject
116 wxSocketFlags m_flags
;
117 wxSocketEventFlags m_eventmask
;
122 wxSocketState() : wxObject() {}
124 DECLARE_NO_COPY_CLASS(wxSocketState
)
127 // wxSocketWaitModeChanger: temporarily change the socket flags affecting its
129 class wxSocketWaitModeChanger
132 // temporarily set the flags to include the flag value which may be either
133 // wxSOCKET_NOWAIT or wxSOCKET_WAITALL
134 wxSocketWaitModeChanger(wxSocketBase
*socket
, int flag
)
136 m_oldflags(socket
->GetFlags())
139 wxASSERT_MSG( flag
== wxSOCKET_WAITALL
|| flag
== wxSOCKET_NOWAIT
,
142 // preserve wxSOCKET_BLOCK value when switching to wxSOCKET_WAITALL
143 // mode but not when switching to wxSOCKET_NOWAIT as the latter is
144 // incompatible with wxSOCKET_BLOCK
145 if ( flag
!= wxSOCKET_NOWAIT
)
146 flag
|= m_oldflags
& wxSOCKET_BLOCK
;
148 socket
->SetFlags(flag
);
151 ~wxSocketWaitModeChanger()
153 m_socket
->SetFlags(m_oldflags
);
157 wxSocketBase
* const m_socket
;
158 const int m_oldflags
;
160 DECLARE_NO_COPY_CLASS(wxSocketWaitModeChanger
)
163 // wxSocketRead/WriteGuard are instantiated before starting reading
164 // from/writing to the socket
165 class wxSocketReadGuard
168 wxSocketReadGuard(wxSocketBase
*socket
)
171 wxASSERT_MSG( !m_socket
->m_reading
, "read reentrancy?" );
173 m_socket
->m_reading
= true;
178 m_socket
->m_reading
= false;
180 m_socket
->m_impl
->ReenableEvents(wxSOCKET_INPUT_FLAG
);
184 wxSocketBase
* const m_socket
;
186 DECLARE_NO_COPY_CLASS(wxSocketReadGuard
)
189 class wxSocketWriteGuard
192 wxSocketWriteGuard(wxSocketBase
*socket
)
195 wxASSERT_MSG( !m_socket
->m_writing
, "write reentrancy?" );
197 m_socket
->m_writing
= true;
199 m_socket
->m_impl
->ReenableEvents(wxSOCKET_OUTPUT_FLAG
);
202 ~wxSocketWriteGuard()
204 m_socket
->m_writing
= false;
208 wxSocketBase
* const m_socket
;
210 DECLARE_NO_COPY_CLASS(wxSocketWriteGuard
)
213 // ============================================================================
215 // ============================================================================
217 wxSocketManager
*wxSocketManager::ms_manager
= NULL
;
220 void wxSocketManager::Set(wxSocketManager
*manager
)
222 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
224 ms_manager
= manager
;
228 void wxSocketManager::Init()
230 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
233 Details: Initialize() creates a hidden window as a sink for socket
234 events, such as 'read completed'. wxMSW has only one message loop
235 for the main thread. If Initialize is called in a secondary thread,
236 the socket window will be created for the secondary thread, but
237 since there is no message loop on this thread, it will never
238 receive events and all socket operations will time out.
239 BTW, the main thread must not be stopped using sleep or block
240 on a semaphore (a bad idea in any case) or socket operations
243 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
244 the main thread. Because secondary threads do not have run loops,
245 adding event notifications to the "Current" loop would have no
246 effect at all, events would never fire.
248 wxASSERT_MSG( wxIsMainThread(),
249 "sockets must be initialized from the main thread" );
251 wxAppConsole
* const app
= wxAppConsole::GetInstance();
252 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
254 ms_manager
= app
->GetTraits()->GetSocketManager();
257 // ==========================================================================
259 // ==========================================================================
261 wxSocketImpl::wxSocketImpl(wxSocketBase
& wxsocket
)
262 : m_wxsocket(&wxsocket
)
264 m_fd
= INVALID_SOCKET
;
265 m_error
= wxSOCKET_NOERROR
;
269 SetTimeout(wxsocket
.GetTimeout() * 1000);
271 m_establishing
= false;
275 m_initialRecvBufferSize
= -1;
276 m_initialSendBufferSize
= -1;
279 wxSocketImpl::~wxSocketImpl()
281 if ( m_fd
!= INVALID_SOCKET
)
285 bool wxSocketImpl::PreCreateCheck(const wxSockAddressImpl
& addr
)
287 if ( m_fd
!= INVALID_SOCKET
)
289 m_error
= wxSOCKET_INVSOCK
;
295 m_error
= wxSOCKET_INVADDR
;
302 void wxSocketImpl::PostCreation()
304 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
306 EnableSocketOption(SO_NOSIGPIPE
);
310 EnableSocketOption(SO_REUSEADDR
);
314 wxASSERT_MSG( !m_stream
, "broadcasting is for datagram sockets only" );
316 EnableSocketOption(SO_BROADCAST
);
319 if ( m_initialRecvBufferSize
>= 0 )
320 SetSocketOption(SO_RCVBUF
, m_initialRecvBufferSize
);
321 if ( m_initialSendBufferSize
>= 0 )
322 SetSocketOption(SO_SNDBUF
, m_initialSendBufferSize
);
324 // we always put our sockets in unblocked mode and handle blocking
325 // ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
326 UnblockAndRegisterWithEventLoop();
329 wxSocketError
wxSocketImpl::UpdateLocalAddress()
331 WX_SOCKLEN_T lenAddr
= m_local
.GetLen();
332 if ( getsockname(m_fd
, m_local
.GetWritableAddr(), &lenAddr
) != 0 )
335 m_error
= wxSOCKET_IOERR
;
339 return wxSOCKET_NOERROR
;
342 wxSocketError
wxSocketImpl::CreateServer()
344 if ( !PreCreateCheck(m_local
) )
350 // do create the socket
351 m_fd
= socket(m_local
.GetFamily(), SOCK_STREAM
, 0);
353 if ( m_fd
== INVALID_SOCKET
)
355 m_error
= wxSOCKET_IOERR
;
356 return wxSOCKET_IOERR
;
361 // and then bind to and listen on it
363 // FIXME: should we test for m_dobind here?
364 if ( bind(m_fd
, m_local
.GetAddr(), m_local
.GetLen()) != 0 )
365 m_error
= wxSOCKET_IOERR
;
369 if ( listen(m_fd
, 5) != 0 )
370 m_error
= wxSOCKET_IOERR
;
379 // finally retrieve the address we effectively bound to
380 return UpdateLocalAddress();
383 wxSocketError
wxSocketImpl::CreateClient(bool wait
)
385 if ( !PreCreateCheck(m_peer
) )
388 m_fd
= socket(m_peer
.GetFamily(), SOCK_STREAM
, 0);
390 if ( m_fd
== INVALID_SOCKET
)
392 m_error
= wxSOCKET_IOERR
;
393 return wxSOCKET_IOERR
;
398 // If a local address has been set, then bind to it before calling connect
399 if ( m_local
.IsOk() )
401 if ( bind(m_fd
, m_local
.GetAddr(), m_local
.GetLen()) != 0 )
404 m_error
= wxSOCKET_IOERR
;
410 int rc
= connect(m_fd
, m_peer
.GetAddr(), m_peer
.GetLen());
411 if ( rc
== SOCKET_ERROR
)
413 wxSocketError err
= GetLastError();
414 if ( err
== wxSOCKET_WOULDBLOCK
)
416 m_establishing
= true;
418 // block waiting for connection if we should (otherwise just return
419 // wxSOCKET_WOULDBLOCK to the caller)
422 err
= SelectWithTimeout(wxSOCKET_CONNECTION_FLAG
)
425 m_establishing
= false;
433 m_error
= wxSOCKET_NOERROR
;
440 wxSocketError
wxSocketImpl::CreateUDP()
442 if ( !PreCreateCheck(m_local
) )
448 m_fd
= socket(m_local
.GetFamily(), SOCK_DGRAM
, 0);
450 if ( m_fd
== INVALID_SOCKET
)
452 m_error
= wxSOCKET_IOERR
;
453 return wxSOCKET_IOERR
;
460 if ( bind(m_fd
, m_local
.GetAddr(), m_local
.GetLen()) != 0 )
463 m_error
= wxSOCKET_IOERR
;
467 return UpdateLocalAddress();
470 return wxSOCKET_NOERROR
;
473 wxSocketImpl
*wxSocketImpl::Accept(wxSocketBase
& wxsocket
)
475 wxSockAddressStorage from
;
476 WX_SOCKLEN_T fromlen
= sizeof(from
);
477 const SOCKET fd
= accept(m_fd
, &from
.addr
, &fromlen
);
479 // accepting is similar to reading in the sense that it resets "ready for
480 // read" flag on the socket
481 ReenableEvents(wxSOCKET_INPUT_FLAG
);
483 if ( fd
== INVALID_SOCKET
)
486 wxSocketImpl
* const sock
= Create(wxsocket
);
488 sock
->m_peer
= wxSockAddressImpl(from
.addr
, fromlen
);
490 sock
->UnblockAndRegisterWithEventLoop();
496 void wxSocketImpl::Close()
498 if ( m_fd
!= INVALID_SOCKET
)
501 m_fd
= INVALID_SOCKET
;
505 void wxSocketImpl::Shutdown()
507 if ( m_fd
!= INVALID_SOCKET
)
509 shutdown(m_fd
, 1 /* SD_SEND */);
515 * Sets the timeout for blocking calls. Time is expressed in
518 void wxSocketImpl::SetTimeout(unsigned long millis
)
520 SetTimeValFromMS(m_timeout
, millis
);
523 void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event
)
525 m_wxsocket
->OnRequest(event
);
528 /* Address handling */
529 wxSocketError
wxSocketImpl::SetLocal(const wxSockAddressImpl
& local
)
531 /* the socket must be initialized, or it must be a server */
532 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
534 m_error
= wxSOCKET_INVSOCK
;
535 return wxSOCKET_INVSOCK
;
540 m_error
= wxSOCKET_INVADDR
;
541 return wxSOCKET_INVADDR
;
546 return wxSOCKET_NOERROR
;
549 wxSocketError
wxSocketImpl::SetPeer(const wxSockAddressImpl
& peer
)
553 m_error
= wxSOCKET_INVADDR
;
554 return wxSOCKET_INVADDR
;
559 return wxSOCKET_NOERROR
;
562 const wxSockAddressImpl
& wxSocketImpl::GetLocal()
564 if ( !m_local
.IsOk() )
565 UpdateLocalAddress();
570 // ----------------------------------------------------------------------------
572 // ----------------------------------------------------------------------------
574 // this macro wraps the given expression (normally a syscall) in a loop which
575 // ignores any interruptions, i.e. reevaluates it again if it failed and errno
578 #define DO_WHILE_EINTR( rc, syscall ) \
582 while ( rc == -1 && errno == EINTR )
584 #define DO_WHILE_EINTR( rc, syscall ) rc = (syscall)
587 int wxSocketImpl::RecvStream(void *buffer
, int size
)
590 DO_WHILE_EINTR( ret
, recv(m_fd
, static_cast<char *>(buffer
), size
, 0) );
594 // receiving 0 bytes for a TCP socket indicates that the connection was
595 // closed by peer so shut down our end as well (for UDP sockets empty
596 // datagrams are also possible)
597 m_establishing
= false;
598 NotifyOnStateChange(wxSOCKET_LOST
);
602 // do not return an error in this case however
608 int wxSocketImpl::SendStream(const void *buffer
, int size
)
611 DO_WHILE_EINTR( ret
, send(m_fd
, static_cast<const char *>(buffer
), size
,
612 wxSOCKET_MSG_NOSIGNAL
) );
617 int wxSocketImpl::RecvDgram(void *buffer
, int size
)
619 wxSockAddressStorage from
;
620 WX_SOCKLEN_T fromlen
= sizeof(from
);
623 DO_WHILE_EINTR( ret
, recvfrom(m_fd
, static_cast<char *>(buffer
), size
,
624 0, &from
.addr
, &fromlen
) );
626 if ( ret
== SOCKET_ERROR
)
629 m_peer
= wxSockAddressImpl(from
.addr
, fromlen
);
630 if ( !m_peer
.IsOk() )
636 int wxSocketImpl::SendDgram(const void *buffer
, int size
)
638 if ( !m_peer
.IsOk() )
640 m_error
= wxSOCKET_INVADDR
;
645 DO_WHILE_EINTR( ret
, sendto(m_fd
, static_cast<const char *>(buffer
), size
,
646 0, m_peer
.GetAddr(), m_peer
.GetLen()) );
651 int wxSocketImpl::Read(void *buffer
, int size
)
653 // server sockets can't be used for IO, only to accept new connections
654 if ( m_fd
== INVALID_SOCKET
|| m_server
)
656 m_error
= wxSOCKET_INVSOCK
;
660 int ret
= m_stream
? RecvStream(buffer
, size
)
661 : RecvDgram(buffer
, size
);
663 m_error
= ret
== SOCKET_ERROR
? GetLastError() : wxSOCKET_NOERROR
;
668 int wxSocketImpl::Write(const void *buffer
, int size
)
670 if ( m_fd
== INVALID_SOCKET
|| m_server
)
672 m_error
= wxSOCKET_INVSOCK
;
676 int ret
= m_stream
? SendStream(buffer
, size
)
677 : SendDgram(buffer
, size
);
679 m_error
= ret
== SOCKET_ERROR
? GetLastError() : wxSOCKET_NOERROR
;
684 // ==========================================================================
686 // ==========================================================================
688 // --------------------------------------------------------------------------
689 // Initialization and shutdown
690 // --------------------------------------------------------------------------
692 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
693 // to m_countInit with a crit section
694 size_t wxSocketBase::m_countInit
= 0;
696 bool wxSocketBase::IsInitialized()
698 return m_countInit
> 0;
701 bool wxSocketBase::Initialize()
703 if ( !m_countInit
++ )
705 wxSocketManager
* const manager
= wxSocketManager::Get();
706 if ( !manager
|| !manager
->OnInit() )
717 void wxSocketBase::Shutdown()
719 // we should be initialized
720 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
721 if ( --m_countInit
== 0 )
723 wxSocketManager
* const manager
= wxSocketManager::Get();
724 wxCHECK_RET( manager
, "should have a socket manager" );
730 // --------------------------------------------------------------------------
732 // --------------------------------------------------------------------------
734 void wxSocketBase::Init()
737 m_type
= wxSOCKET_UNINIT
;
748 m_beingDeleted
= false;
763 if ( !IsInitialized() )
765 // this Initialize() will be undone by wxSocketModule::OnExit(), all
766 // the other calls to it should be matched by a call to Shutdown()
771 wxSocketBase::wxSocketBase()
776 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
785 wxSocketBase::~wxSocketBase()
787 // Just in case the app called Destroy() *and* then deleted the socket
788 // immediately: don't leave dangling pointers.
789 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
791 traits
->RemoveFromPendingDelete(this);
793 // Shutdown and close the socket
797 // Destroy the implementation object
800 // Free the pushback buffer
805 bool wxSocketBase::Destroy()
807 // Delayed destruction: the socket will be deleted during the next idle
808 // loop iteration. This ensures that all pending events have been
810 m_beingDeleted
= true;
812 // Shutdown and close the socket
815 // Suppress events from now on
818 // schedule this object for deletion
819 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
822 // let the traits object decide what to do with us
823 traits
->ScheduleForDestroy(this);
825 else // no app or no traits
827 // in wxBase we might have no app object at all, don't leak memory
834 // ----------------------------------------------------------------------------
836 // ----------------------------------------------------------------------------
838 void wxSocketBase::SetError(wxSocketError error
)
840 m_impl
->m_error
= error
;
843 wxSocketError
wxSocketBase::LastError() const
845 return m_impl
->GetError();
848 // --------------------------------------------------------------------------
850 // --------------------------------------------------------------------------
852 // The following IO operations update m_lcount:
853 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
854 bool wxSocketBase::Close()
856 // Interrupt pending waits
862 m_establishing
= false;
866 void wxSocketBase::ShutdownOutput()
872 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
874 wxSocketReadGuard
read(this);
876 m_lcount
= DoRead(buffer
, nbytes
);
881 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
883 wxCHECK_MSG( m_impl
, 0, "socket must be valid" );
885 // We use pointer arithmetic here which doesn't work with void pointers.
886 char *buffer
= static_cast<char *>(buffer_
);
887 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
889 // Try the push back buffer first, even before checking whether the socket
890 // is valid to allow reading previously pushed back data from an already
892 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
898 // our socket is non-blocking so Read() will return immediately if
899 // there is nothing to read yet and it's more efficient to try it first
900 // before entering DoWait() which is going to start dispatching GUI
901 // events and, even more importantly, we must do this under Windows
902 // where we're not going to get notifications about socket being ready
903 // for reading before we read all the existing data from it
904 const int ret
= m_connected
? m_impl
->Read(buffer
, nbytes
) : 0;
907 if ( m_impl
->GetLastError() == wxSOCKET_WOULDBLOCK
)
909 // if we don't want to wait, just return immediately
910 if ( m_flags
& wxSOCKET_NOWAIT
)
913 // otherwise wait until the socket becomes ready for reading or
914 // an error occurs on it
915 if ( !DoWaitWithTimeout(wxSOCKET_INPUT_FLAG
) )
917 // and exit if the timeout elapsed before it did
918 SetError(wxSOCKET_TIMEDOUT
);
927 SetError(wxSOCKET_IOERR
);
933 // for connection-oriented (e.g. TCP) sockets we can only read
934 // 0 bytes if the other end has been closed, and for connectionless
935 // ones (UDP) this flag doesn't make sense anyhow so we can set it
936 // to true too without doing any harm
939 // we're not going to read anything else and so if we haven't read
940 // anything (or not everything in wxSOCKET_WAITALL case) already,
942 if ( (m_flags
& wxSOCKET_WAITALL
) || !total
)
943 SetError(wxSOCKET_IOERR
);
949 // if we are happy to read something and not the entire nbytes bytes,
951 if ( !(m_flags
& wxSOCKET_WAITALL
) )
961 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
965 unsigned char sig
[4];
966 unsigned char len
[4];
969 wxSocketReadGuard
read(this);
971 wxSocketWaitModeChanger
changeFlags(this, wxSOCKET_WAITALL
);
974 if ( DoRead(&msg
, sizeof(msg
)) == sizeof(msg
) )
976 wxUint32 sig
= (wxUint32
)msg
.sig
[0];
977 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
978 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
979 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
981 if ( sig
== 0xfeeddead )
983 wxUint32 len
= (wxUint32
)msg
.len
[0];
984 len
|= (wxUint32
)(msg
.len
[1] << 8);
985 len
|= (wxUint32
)(msg
.len
[2] << 16);
986 len
|= (wxUint32
)(msg
.len
[3] << 24);
997 // Don't attempt to read if the msg was zero bytes long.
998 m_lcount
= len
? DoRead(buffer
, len
) : 0;
1002 char discard_buffer
[MAX_DISCARD_SIZE
];
1005 // NOTE: discarded bytes don't add to m_lcount.
1008 discard_len
= len2
> MAX_DISCARD_SIZE
1011 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
1012 len2
-= (wxUint32
)discard_len
;
1014 while ((discard_len
> 0) && len2
);
1017 if ( !len2
&& DoRead(&msg
, sizeof(msg
)) == sizeof(msg
) )
1019 sig
= (wxUint32
)msg
.sig
[0];
1020 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
1021 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
1022 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
1024 if ( sig
== 0xdeadfeed )
1031 SetError(wxSOCKET_IOERR
);
1036 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
1038 wxSocketReadGuard
read(this);
1040 m_lcount
= DoRead(buffer
, nbytes
);
1042 Pushback(buffer
, m_lcount
);
1047 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
1049 wxSocketWriteGuard
write(this);
1051 m_lcount
= DoWrite(buffer
, nbytes
);
1056 // This function is a mirror image of DoRead() except that it doesn't use the
1057 // push back buffer and doesn't treat 0 return value specially (normally this
1058 // shouldn't happen at all here), so please see comments there for explanations
1059 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
1061 wxCHECK_MSG( m_impl
, 0, "socket must be valid" );
1063 const char *buffer
= static_cast<const char *>(buffer_
);
1064 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1071 if ( (m_flags
& wxSOCKET_WAITALL
) || !total
)
1072 SetError(wxSOCKET_IOERR
);
1076 const int ret
= m_impl
->Write(buffer
, nbytes
);
1079 if ( m_impl
->GetLastError() == wxSOCKET_WOULDBLOCK
)
1081 if ( m_flags
& wxSOCKET_NOWAIT
)
1084 if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG
) )
1086 SetError(wxSOCKET_TIMEDOUT
);
1092 else // "real" error
1094 SetError(wxSOCKET_IOERR
);
1101 if ( !(m_flags
& wxSOCKET_WAITALL
) )
1111 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
1115 unsigned char sig
[4];
1116 unsigned char len
[4];
1119 wxSocketWriteGuard
write(this);
1121 wxSocketWaitModeChanger
changeFlags(this, wxSOCKET_WAITALL
);
1123 msg
.sig
[0] = (unsigned char) 0xad;
1124 msg
.sig
[1] = (unsigned char) 0xde;
1125 msg
.sig
[2] = (unsigned char) 0xed;
1126 msg
.sig
[3] = (unsigned char) 0xfe;
1128 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
1129 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
1130 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
1131 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
1134 if ( DoWrite(&msg
, sizeof(msg
)) == sizeof(msg
) )
1136 m_lcount
= DoWrite(buffer
, nbytes
);
1137 if ( m_lcount
== nbytes
)
1139 msg
.sig
[0] = (unsigned char) 0xed;
1140 msg
.sig
[1] = (unsigned char) 0xfe;
1141 msg
.sig
[2] = (unsigned char) 0xad;
1142 msg
.sig
[3] = (unsigned char) 0xde;
1146 msg
.len
[3] = (char) 0;
1148 if ( DoWrite(&msg
, sizeof(msg
)) == sizeof(msg
))
1154 SetError(wxSOCKET_IOERR
);
1159 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
1162 Pushback(buffer
, nbytes
);
1164 SetError(wxSOCKET_NOERROR
);
1170 wxSocketBase
& wxSocketBase::Discard()
1172 char *buffer
= new char[MAX_DISCARD_SIZE
];
1176 wxSocketReadGuard
read(this);
1178 wxSocketWaitModeChanger
changeFlags(this, wxSOCKET_NOWAIT
);
1182 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
1185 while (ret
== MAX_DISCARD_SIZE
);
1189 SetError(wxSOCKET_NOERROR
);
1194 // --------------------------------------------------------------------------
1196 // --------------------------------------------------------------------------
1199 This function will check for the events specified in the flags parameter,
1200 and it will return a mask indicating which operations can be performed.
1202 wxSocketEventFlags
wxSocketImpl::Select(wxSocketEventFlags flags
,
1203 const timeval
*timeout
)
1205 if ( m_fd
== INVALID_SOCKET
)
1206 return (wxSOCKET_LOST_FLAG
& flags
);
1212 tv
.tv_sec
= tv
.tv_usec
= 0;
1214 // prepare the FD sets, passing NULL for the one(s) we don't use
1216 readfds
, *preadfds
= NULL
,
1217 writefds
, *pwritefds
= NULL
,
1218 exceptfds
; // always want to know about errors
1220 if ( flags
& wxSOCKET_INPUT_FLAG
)
1222 preadfds
= &readfds
;
1223 wxFD_ZERO(preadfds
);
1224 wxFD_SET(m_fd
, preadfds
);
1227 // when using non-blocking connect() the socket becomes connected
1228 // (successfully or not) when it becomes writable
1229 if ( flags
& (wxSOCKET_OUTPUT_FLAG
| wxSOCKET_CONNECTION_FLAG
) )
1231 pwritefds
= &writefds
;
1232 wxFD_ZERO(pwritefds
);
1233 wxFD_SET(m_fd
, pwritefds
);
1236 wxFD_ZERO(&exceptfds
);
1237 wxFD_SET(m_fd
, &exceptfds
);
1239 const int rc
= select(m_fd
+ 1, preadfds
, pwritefds
, &exceptfds
, &tv
);
1241 // check for errors first
1242 if ( rc
== -1 || wxFD_ISSET(m_fd
, &exceptfds
) )
1244 m_establishing
= false;
1246 return wxSOCKET_LOST_FLAG
& flags
;
1252 wxASSERT_MSG( rc
== 1, "unexpected select() return value" );
1254 wxSocketEventFlags detected
= 0;
1255 if ( preadfds
&& wxFD_ISSET(m_fd
, preadfds
) )
1256 detected
|= wxSOCKET_INPUT_FLAG
;
1258 if ( pwritefds
&& wxFD_ISSET(m_fd
, pwritefds
) )
1260 // check for the case of non-blocking connect()
1261 if ( m_establishing
&& !m_server
)
1264 SOCKOPTLEN_T len
= sizeof(error
);
1265 m_establishing
= false;
1266 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1269 detected
= wxSOCKET_LOST_FLAG
;
1271 detected
|= wxSOCKET_CONNECTION_FLAG
;
1273 else // not called to get non-blocking connect() status
1275 detected
|= wxSOCKET_OUTPUT_FLAG
;
1279 return detected
& flags
;
1283 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1285 // Use either the provided timeout or the default timeout value associated
1286 // with this socket.
1288 // TODO: allow waiting forever, see #9443
1289 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1290 : seconds
* 1000 + milliseconds
;
1292 return DoWait(timeout
, flags
);
1296 wxSocketBase::DoWait(long timeout
, wxSocketEventFlags flags
)
1298 wxCHECK_MSG( m_impl
, -1, "can't wait on invalid socket" );
1300 // we're never going to become ready if we're not connected (any more)
1301 if ( !m_connected
&& !m_establishing
)
1304 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1305 m_interrupt
= false;
1308 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1310 // Get the active event loop which we'll use for the message dispatching
1311 // when running in the main thread unless this was explicitly disabled by
1312 // setting wxSOCKET_BLOCK flag
1313 wxEventLoopBase
*eventLoop
;
1314 if ( !(m_flags
& wxSOCKET_BLOCK
) && wxIsMainThread() )
1316 eventLoop
= wxEventLoop::GetActive();
1318 else // in worker thread
1320 // We never dispatch messages from threads other than the main one.
1324 // Wait until we receive the event we're waiting for or the timeout expires
1325 // (but note that we always execute the loop at least once, even if timeout
1326 // is 0 as this is used for polling)
1328 for ( bool firstTime
= true; !m_interrupt
; firstTime
= false )
1330 long timeLeft
= wxMilliClockToLong(timeEnd
- wxGetLocalTimeMillis());
1339 wxSocketEventFlags events
;
1342 // reset them before starting to wait
1345 eventLoop
->DispatchTimeout(timeLeft
);
1347 events
= m_eventsgot
;
1349 else // no event loop or waiting in another thread
1351 // as explained below, we should always check for wxSOCKET_LOST_FLAG
1353 SetTimeValFromMS(tv
, timeLeft
);
1354 events
= m_impl
->Select(flags
| wxSOCKET_LOST_FLAG
, &tv
);
1357 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1358 // it, as continuing to wait for anything else after getting it is
1360 if ( events
& wxSOCKET_LOST_FLAG
)
1362 m_connected
= false;
1363 m_establishing
= false;
1368 // otherwise mask out the bits we're not interested in
1371 // Incoming connection (server) or connection established (client)?
1372 if ( events
& wxSOCKET_CONNECTION_FLAG
)
1375 m_establishing
= false;
1380 // Data available or output buffer ready?
1381 if ( (events
& wxSOCKET_INPUT_FLAG
) || (events
& wxSOCKET_OUTPUT_FLAG
) )
1391 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1393 return DoWait(seconds
, milliseconds
,
1394 wxSOCKET_INPUT_FLAG
|
1395 wxSOCKET_OUTPUT_FLAG
|
1396 wxSOCKET_CONNECTION_FLAG
) != 0;
1399 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1401 // Check pushback buffer before entering DoWait
1405 // Check if the socket is not already ready for input, if it is, there is
1406 // no need to start waiting for it (worse, we'll actually never get a
1407 // notification about the socket becoming ready if it is already under
1409 if ( m_impl
->Select(wxSOCKET_INPUT_FLAG
) )
1412 return DoWait(seconds
, milliseconds
, wxSOCKET_INPUT_FLAG
) != 0;
1416 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1418 if ( m_impl
->Select(wxSOCKET_OUTPUT_FLAG
) )
1421 return DoWait(seconds
, milliseconds
, wxSOCKET_OUTPUT_FLAG
) != 0;
1424 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1426 return DoWait(seconds
, milliseconds
, wxSOCKET_LOST_FLAG
) == -1;
1429 // --------------------------------------------------------------------------
1431 // --------------------------------------------------------------------------
1434 // Get local or peer address
1437 bool wxSocketBase::GetPeer(wxSockAddress
& addr
) const
1439 wxCHECK_MSG( m_impl
, false, "invalid socket" );
1441 const wxSockAddressImpl
& peer
= m_impl
->GetPeer();
1445 addr
.SetAddress(peer
);
1450 bool wxSocketBase::GetLocal(wxSockAddress
& addr
) const
1452 wxCHECK_MSG( m_impl
, false, "invalid socket" );
1454 const wxSockAddressImpl
& local
= m_impl
->GetLocal();
1455 if ( !local
.IsOk() )
1458 addr
.SetAddress(local
);
1464 // Save and restore socket state
1467 void wxSocketBase::SaveState()
1469 wxSocketState
*state
;
1471 state
= new wxSocketState();
1473 state
->m_flags
= m_flags
;
1474 state
->m_notify
= m_notify
;
1475 state
->m_eventmask
= m_eventmask
;
1476 state
->m_clientData
= m_clientData
;
1478 m_states
.Append(state
);
1481 void wxSocketBase::RestoreState()
1483 wxList::compatibility_iterator node
;
1484 wxSocketState
*state
;
1486 node
= m_states
.GetLast();
1490 state
= (wxSocketState
*)node
->GetData();
1492 m_flags
= state
->m_flags
;
1493 m_notify
= state
->m_notify
;
1494 m_eventmask
= state
->m_eventmask
;
1495 m_clientData
= state
->m_clientData
;
1497 m_states
.Erase(node
);
1502 // Timeout and flags
1505 void wxSocketBase::SetTimeout(long seconds
)
1507 m_timeout
= seconds
;
1510 m_impl
->SetTimeout(m_timeout
* 1000);
1513 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1515 // Do some sanity checking on the flags used: not all values can be used
1517 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1518 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1519 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1520 "wxSOCKET_NOWAIT doesn't make sense" );
1526 // --------------------------------------------------------------------------
1528 // --------------------------------------------------------------------------
1530 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1532 wxSocketEventFlags flag
= 0;
1533 switch ( notification
)
1535 case wxSOCKET_INPUT
:
1536 flag
= wxSOCKET_INPUT_FLAG
;
1539 case wxSOCKET_OUTPUT
:
1540 flag
= wxSOCKET_OUTPUT_FLAG
;
1543 case wxSOCKET_CONNECTION
:
1544 flag
= wxSOCKET_CONNECTION_FLAG
;
1548 flag
= wxSOCKET_LOST_FLAG
;
1552 wxFAIL_MSG( "unknown wxSocket notification" );
1555 // if we lost the connection the socket is now closed
1556 if ( notification
== wxSOCKET_LOST
)
1559 // remember the events which were generated for this socket, we're going to
1560 // use this in DoWait()
1561 m_eventsgot
|= flag
;
1563 // send the wx event if enabled and we're interested in it
1564 if ( m_notify
&& (m_eventmask
& flag
) && m_handler
)
1566 // don't generate the events when we're inside DoWait() called from our
1567 // own code as we are going to consume the data that has just become
1568 // available ourselves and the user code won't see it at all
1569 if ( (notification
== wxSOCKET_INPUT
&& m_reading
) ||
1570 (notification
== wxSOCKET_OUTPUT
&& m_writing
) )
1575 wxSocketEvent
event(m_id
);
1576 event
.m_event
= notification
;
1577 event
.m_clientData
= m_clientData
;
1578 event
.SetEventObject(this);
1580 m_handler
->AddPendingEvent(event
);
1584 void wxSocketBase::Notify(bool notify
)
1589 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1591 m_eventmask
= flags
;
1594 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1596 m_handler
= &handler
;
1600 // --------------------------------------------------------------------------
1602 // --------------------------------------------------------------------------
1604 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1608 if (m_unread
== NULL
)
1609 m_unread
= malloc(size
);
1614 tmp
= malloc(m_unrd_size
+ size
);
1615 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1621 m_unrd_size
+= size
;
1623 memcpy(m_unread
, buffer
, size
);
1626 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1628 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1633 if (size
> (m_unrd_size
-m_unrd_cur
))
1634 size
= m_unrd_size
-m_unrd_cur
;
1636 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1641 if (m_unrd_size
== m_unrd_cur
)
1654 // ==========================================================================
1656 // ==========================================================================
1658 // --------------------------------------------------------------------------
1660 // --------------------------------------------------------------------------
1662 wxSocketServer::wxSocketServer(const wxSockAddress
& addr
,
1663 wxSocketFlags flags
)
1664 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1666 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1668 m_impl
= wxSocketImpl::Create(*this);
1672 wxLogTrace( wxTRACE_Socket
, _T("*** Failed to create m_impl") );
1676 // Setup the socket as server
1677 m_impl
->SetLocal(addr
.GetAddress());
1679 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1680 m_impl
->SetReusable();
1682 if (GetFlags() & wxSOCKET_BROADCAST
) {
1683 m_impl
->SetBroadcast();
1685 if (GetFlags() & wxSOCKET_NOBIND
) {
1686 m_impl
->DontDoBind();
1689 if (m_impl
->CreateServer() != wxSOCKET_NOERROR
)
1694 wxLogTrace( wxTRACE_Socket
, _T("*** CreateServer() failed") );
1698 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_impl
->m_fd
);
1701 // --------------------------------------------------------------------------
1703 // --------------------------------------------------------------------------
1705 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1707 if ( !m_impl
|| (m_impl
->m_fd
== INVALID_SOCKET
) || !m_impl
->IsServer() )
1709 wxFAIL_MSG( "can only be called for a valid server socket" );
1711 SetError(wxSOCKET_INVSOCK
);
1718 // wait until we get a connection
1719 if ( !m_impl
->SelectWithTimeout(wxSOCKET_INPUT_FLAG
) )
1721 SetError(wxSOCKET_TIMEDOUT
);
1727 sock
.m_impl
= m_impl
->Accept(sock
);
1731 SetError(m_impl
->GetLastError());
1736 sock
.m_type
= wxSOCKET_BASE
;
1737 sock
.m_connected
= true;
1742 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1744 wxSocketBase
* sock
= new wxSocketBase();
1746 sock
->SetFlags(m_flags
);
1748 if (!AcceptWith(*sock
, wait
))
1757 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1759 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
) == 1;
1762 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1764 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1766 SOCKOPTLEN_T lenreal
= *optlen
;
1767 if ( getsockopt(m_impl
->m_fd
, level
, optname
,
1768 static_cast<char *>(optval
), &lenreal
) != 0 )
1777 wxSocketBase::SetOption(int level
, int optname
, const void *optval
, int optlen
)
1779 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1781 return setsockopt(m_impl
->m_fd
, level
, optname
,
1782 static_cast<const char *>(optval
), optlen
) == 0;
1785 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1787 m_localAddress
= local
;
1792 // ==========================================================================
1794 // ==========================================================================
1796 // --------------------------------------------------------------------------
1798 // --------------------------------------------------------------------------
1800 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1801 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1803 m_initialRecvBufferSize
=
1804 m_initialSendBufferSize
= -1;
1807 // --------------------------------------------------------------------------
1809 // --------------------------------------------------------------------------
1811 bool wxSocketClient::DoConnect(const wxSockAddress
& remote
,
1812 const wxSockAddress
* local
,
1817 // Shutdown and destroy the old socket
1822 m_connected
= false;
1823 m_establishing
= false;
1825 // Create and set up the new one
1826 m_impl
= wxSocketImpl::Create(*this);
1830 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1831 if (GetFlags() & wxSOCKET_REUSEADDR
)
1832 m_impl
->SetReusable();
1833 if (GetFlags() & wxSOCKET_BROADCAST
)
1834 m_impl
->SetBroadcast();
1835 if (GetFlags() & wxSOCKET_NOBIND
)
1836 m_impl
->DontDoBind();
1838 // Bind to the local IP address and port, when provided or if one had been
1840 if ( !local
&& m_localAddress
.GetAddress().IsOk() )
1841 local
= &m_localAddress
;
1844 m_impl
->SetLocal(local
->GetAddress());
1846 m_impl
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1848 m_impl
->SetPeer(remote
.GetAddress());
1850 // Finally do create the socket and connect to the peer
1851 const wxSocketError err
= m_impl
->CreateClient(wait
);
1853 if ( err
!= wxSOCKET_NOERROR
)
1855 if ( err
== wxSOCKET_WOULDBLOCK
)
1857 wxASSERT_MSG( !wait
, "shouldn't get this for blocking connect" );
1859 m_establishing
= true;
1869 bool wxSocketClient::Connect(const wxSockAddress
& remote
, bool wait
)
1871 return DoConnect(remote
, NULL
, wait
);
1874 bool wxSocketClient::Connect(const wxSockAddress
& remote
,
1875 const wxSockAddress
& local
,
1878 return DoConnect(remote
, &local
, wait
);
1881 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1885 // this happens if the initial attempt to connect succeeded without
1890 wxCHECK_MSG( m_establishing
&& m_impl
, false,
1891 "No connection establishment attempt in progress" );
1893 // notice that we return true even if DoWait() returned -1, i.e. if an
1894 // error occurred and connection was lost: this is intentional as we should
1895 // return false only if timeout expired without anything happening
1896 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
) != 0;
1899 // ==========================================================================
1901 // ==========================================================================
1903 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1904 wxSocketFlags flags
)
1905 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1907 // Create the socket
1908 m_impl
= wxSocketImpl::Create(*this);
1913 // Setup the socket as non connection oriented
1914 m_impl
->SetLocal(addr
.GetAddress());
1915 if (flags
& wxSOCKET_REUSEADDR
)
1917 m_impl
->SetReusable();
1919 if (GetFlags() & wxSOCKET_BROADCAST
)
1921 m_impl
->SetBroadcast();
1923 if (GetFlags() & wxSOCKET_NOBIND
)
1925 m_impl
->DontDoBind();
1928 if ( m_impl
->CreateUDP() != wxSOCKET_NOERROR
)
1935 // Initialize all stuff
1936 m_connected
= false;
1937 m_establishing
= false;
1940 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1949 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1953 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1955 m_impl
->SetPeer(addr
.GetAddress());
1960 // ==========================================================================
1962 // ==========================================================================
1964 class wxSocketModule
: public wxModule
1967 virtual bool OnInit()
1969 // wxSocketBase will call Initialize() itself only if sockets are
1970 // really used, don't do it from here
1974 virtual void OnExit()
1976 if ( wxSocketBase::IsInitialized() )
1977 wxSocketBase::Shutdown();
1981 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1984 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1986 #endif // wxUSE_SOCKETS