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 wxDEFINE_EVENT(wxEVT_SOCKET
, wxSocketEvent
);
85 #define MAX_DISCARD_SIZE (10 * 1024)
87 #define wxTRACE_Socket _T("wxSocket")
89 // --------------------------------------------------------------------------
91 // --------------------------------------------------------------------------
93 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
94 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
95 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
96 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
97 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
99 // ----------------------------------------------------------------------------
101 // ----------------------------------------------------------------------------
106 void SetTimeValFromMS(timeval
& tv
, unsigned long ms
)
108 tv
.tv_sec
= (ms
/ 1000);
109 tv
.tv_usec
= (ms
% 1000) * 1000;
112 } // anonymous namespace
114 // --------------------------------------------------------------------------
116 // --------------------------------------------------------------------------
118 class wxSocketState
: public wxObject
121 wxSocketFlags m_flags
;
122 wxSocketEventFlags m_eventmask
;
127 wxSocketState() : wxObject() {}
129 DECLARE_NO_COPY_CLASS(wxSocketState
)
132 // wxSocketWaitModeChanger: temporarily change the socket flags affecting its
134 class wxSocketWaitModeChanger
137 // temporarily set the flags to include the flag value which may be either
138 // wxSOCKET_NOWAIT or wxSOCKET_WAITALL
139 wxSocketWaitModeChanger(wxSocketBase
*socket
, int flag
)
141 m_oldflags(socket
->GetFlags())
144 wxASSERT_MSG( flag
== wxSOCKET_WAITALL
|| flag
== wxSOCKET_NOWAIT
,
147 // preserve wxSOCKET_BLOCK value when switching to wxSOCKET_WAITALL
148 // mode but not when switching to wxSOCKET_NOWAIT as the latter is
149 // incompatible with wxSOCKET_BLOCK
150 if ( flag
!= wxSOCKET_NOWAIT
)
151 flag
|= m_oldflags
& wxSOCKET_BLOCK
;
153 socket
->SetFlags(flag
);
156 ~wxSocketWaitModeChanger()
158 m_socket
->SetFlags(m_oldflags
);
162 wxSocketBase
* const m_socket
;
163 const int m_oldflags
;
165 DECLARE_NO_COPY_CLASS(wxSocketWaitModeChanger
)
168 // wxSocketRead/WriteGuard are instantiated before starting reading
169 // from/writing to the socket
170 class wxSocketReadGuard
173 wxSocketReadGuard(wxSocketBase
*socket
)
176 wxASSERT_MSG( !m_socket
->m_reading
, "read reentrancy?" );
178 m_socket
->m_reading
= true;
183 m_socket
->m_reading
= false;
185 m_socket
->m_impl
->ReenableEvents(wxSOCKET_INPUT_FLAG
);
189 wxSocketBase
* const m_socket
;
191 DECLARE_NO_COPY_CLASS(wxSocketReadGuard
)
194 class wxSocketWriteGuard
197 wxSocketWriteGuard(wxSocketBase
*socket
)
200 wxASSERT_MSG( !m_socket
->m_writing
, "write reentrancy?" );
202 m_socket
->m_writing
= true;
204 m_socket
->m_impl
->ReenableEvents(wxSOCKET_OUTPUT_FLAG
);
207 ~wxSocketWriteGuard()
209 m_socket
->m_writing
= false;
213 wxSocketBase
* const m_socket
;
215 DECLARE_NO_COPY_CLASS(wxSocketWriteGuard
)
218 // ============================================================================
220 // ============================================================================
222 wxSocketManager
*wxSocketManager::ms_manager
= NULL
;
225 void wxSocketManager::Set(wxSocketManager
*manager
)
227 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
229 ms_manager
= manager
;
233 void wxSocketManager::Init()
235 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
238 Details: Initialize() creates a hidden window as a sink for socket
239 events, such as 'read completed'. wxMSW has only one message loop
240 for the main thread. If Initialize is called in a secondary thread,
241 the socket window will be created for the secondary thread, but
242 since there is no message loop on this thread, it will never
243 receive events and all socket operations will time out.
244 BTW, the main thread must not be stopped using sleep or block
245 on a semaphore (a bad idea in any case) or socket operations
248 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
249 the main thread. Because secondary threads do not have run loops,
250 adding event notifications to the "Current" loop would have no
251 effect at all, events would never fire.
253 wxASSERT_MSG( wxIsMainThread(),
254 "sockets must be initialized from the main thread" );
256 wxAppConsole
* const app
= wxAppConsole::GetInstance();
257 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
259 ms_manager
= app
->GetTraits()->GetSocketManager();
262 // ==========================================================================
264 // ==========================================================================
266 wxSocketImpl::wxSocketImpl(wxSocketBase
& wxsocket
)
267 : m_wxsocket(&wxsocket
)
269 m_fd
= INVALID_SOCKET
;
270 m_error
= wxSOCKET_NOERROR
;
274 SetTimeout(wxsocket
.GetTimeout() * 1000);
276 m_establishing
= false;
280 m_initialRecvBufferSize
= -1;
281 m_initialSendBufferSize
= -1;
284 wxSocketImpl::~wxSocketImpl()
286 if ( m_fd
!= INVALID_SOCKET
)
290 bool wxSocketImpl::PreCreateCheck(const wxSockAddressImpl
& addr
)
292 if ( m_fd
!= INVALID_SOCKET
)
294 m_error
= wxSOCKET_INVSOCK
;
300 m_error
= wxSOCKET_INVADDR
;
307 void wxSocketImpl::PostCreation()
309 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
311 EnableSocketOption(SO_NOSIGPIPE
);
315 EnableSocketOption(SO_REUSEADDR
);
319 wxASSERT_MSG( !m_stream
, "broadcasting is for datagram sockets only" );
321 EnableSocketOption(SO_BROADCAST
);
324 if ( m_initialRecvBufferSize
>= 0 )
325 SetSocketOption(SO_RCVBUF
, m_initialRecvBufferSize
);
326 if ( m_initialSendBufferSize
>= 0 )
327 SetSocketOption(SO_SNDBUF
, m_initialSendBufferSize
);
329 // we always put our sockets in unblocked mode and handle blocking
330 // ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
331 UnblockAndRegisterWithEventLoop();
334 wxSocketError
wxSocketImpl::UpdateLocalAddress()
336 WX_SOCKLEN_T lenAddr
= m_local
.GetLen();
337 if ( getsockname(m_fd
, m_local
.GetWritableAddr(), &lenAddr
) != 0 )
340 m_error
= wxSOCKET_IOERR
;
344 return wxSOCKET_NOERROR
;
347 wxSocketError
wxSocketImpl::CreateServer()
349 if ( !PreCreateCheck(m_local
) )
355 // do create the socket
356 m_fd
= socket(m_local
.GetFamily(), SOCK_STREAM
, 0);
358 if ( m_fd
== INVALID_SOCKET
)
360 m_error
= wxSOCKET_IOERR
;
361 return wxSOCKET_IOERR
;
366 // and then bind to and listen on it
368 // FIXME: should we test for m_dobind here?
369 if ( bind(m_fd
, m_local
.GetAddr(), m_local
.GetLen()) != 0 )
370 m_error
= wxSOCKET_IOERR
;
374 if ( listen(m_fd
, 5) != 0 )
375 m_error
= wxSOCKET_IOERR
;
384 // finally retrieve the address we effectively bound to
385 return UpdateLocalAddress();
388 wxSocketError
wxSocketImpl::CreateClient(bool wait
)
390 if ( !PreCreateCheck(m_peer
) )
393 m_fd
= socket(m_peer
.GetFamily(), SOCK_STREAM
, 0);
395 if ( m_fd
== INVALID_SOCKET
)
397 m_error
= wxSOCKET_IOERR
;
398 return wxSOCKET_IOERR
;
403 // If a local address has been set, then bind to it before calling connect
404 if ( m_local
.IsOk() )
406 if ( bind(m_fd
, m_local
.GetAddr(), m_local
.GetLen()) != 0 )
409 m_error
= wxSOCKET_IOERR
;
415 int rc
= connect(m_fd
, m_peer
.GetAddr(), m_peer
.GetLen());
416 if ( rc
== SOCKET_ERROR
)
418 wxSocketError err
= GetLastError();
419 if ( err
== wxSOCKET_WOULDBLOCK
)
421 m_establishing
= true;
423 // block waiting for connection if we should (otherwise just return
424 // wxSOCKET_WOULDBLOCK to the caller)
427 err
= SelectWithTimeout(wxSOCKET_CONNECTION_FLAG
)
430 m_establishing
= false;
438 m_error
= wxSOCKET_NOERROR
;
445 wxSocketError
wxSocketImpl::CreateUDP()
447 if ( !PreCreateCheck(m_local
) )
453 m_fd
= socket(m_local
.GetFamily(), SOCK_DGRAM
, 0);
455 if ( m_fd
== INVALID_SOCKET
)
457 m_error
= wxSOCKET_IOERR
;
458 return wxSOCKET_IOERR
;
465 if ( bind(m_fd
, m_local
.GetAddr(), m_local
.GetLen()) != 0 )
468 m_error
= wxSOCKET_IOERR
;
472 return UpdateLocalAddress();
475 return wxSOCKET_NOERROR
;
478 wxSocketImpl
*wxSocketImpl::Accept(wxSocketBase
& wxsocket
)
480 wxSockAddressStorage from
;
481 WX_SOCKLEN_T fromlen
= sizeof(from
);
482 const SOCKET fd
= accept(m_fd
, &from
.addr
, &fromlen
);
484 // accepting is similar to reading in the sense that it resets "ready for
485 // read" flag on the socket
486 ReenableEvents(wxSOCKET_INPUT_FLAG
);
488 if ( fd
== INVALID_SOCKET
)
491 wxSocketImpl
* const sock
= Create(wxsocket
);
493 sock
->m_peer
= wxSockAddressImpl(from
.addr
, fromlen
);
495 sock
->UnblockAndRegisterWithEventLoop();
501 void wxSocketImpl::Close()
503 if ( m_fd
!= INVALID_SOCKET
)
506 m_fd
= INVALID_SOCKET
;
510 void wxSocketImpl::Shutdown()
512 if ( m_fd
!= INVALID_SOCKET
)
514 shutdown(m_fd
, 1 /* SD_SEND */);
520 * Sets the timeout for blocking calls. Time is expressed in
523 void wxSocketImpl::SetTimeout(unsigned long millis
)
525 SetTimeValFromMS(m_timeout
, millis
);
528 void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event
)
530 m_wxsocket
->OnRequest(event
);
533 /* Address handling */
534 wxSocketError
wxSocketImpl::SetLocal(const wxSockAddressImpl
& local
)
536 /* the socket must be initialized, or it must be a server */
537 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
539 m_error
= wxSOCKET_INVSOCK
;
540 return wxSOCKET_INVSOCK
;
545 m_error
= wxSOCKET_INVADDR
;
546 return wxSOCKET_INVADDR
;
551 return wxSOCKET_NOERROR
;
554 wxSocketError
wxSocketImpl::SetPeer(const wxSockAddressImpl
& peer
)
558 m_error
= wxSOCKET_INVADDR
;
559 return wxSOCKET_INVADDR
;
564 return wxSOCKET_NOERROR
;
567 const wxSockAddressImpl
& wxSocketImpl::GetLocal()
569 if ( !m_local
.IsOk() )
570 UpdateLocalAddress();
575 // ----------------------------------------------------------------------------
577 // ----------------------------------------------------------------------------
579 // this macro wraps the given expression (normally a syscall) in a loop which
580 // ignores any interruptions, i.e. reevaluates it again if it failed and errno
583 #define DO_WHILE_EINTR( rc, syscall ) \
587 while ( rc == -1 && errno == EINTR )
589 #define DO_WHILE_EINTR( rc, syscall ) rc = (syscall)
592 int wxSocketImpl::RecvStream(void *buffer
, int size
)
595 DO_WHILE_EINTR( ret
, recv(m_fd
, static_cast<char *>(buffer
), size
, 0) );
599 // receiving 0 bytes for a TCP socket indicates that the connection was
600 // closed by peer so shut down our end as well (for UDP sockets empty
601 // datagrams are also possible)
602 m_establishing
= false;
603 NotifyOnStateChange(wxSOCKET_LOST
);
607 // do not return an error in this case however
613 int wxSocketImpl::SendStream(const void *buffer
, int size
)
616 DO_WHILE_EINTR( ret
, send(m_fd
, static_cast<const char *>(buffer
), size
,
617 wxSOCKET_MSG_NOSIGNAL
) );
622 int wxSocketImpl::RecvDgram(void *buffer
, int size
)
624 wxSockAddressStorage from
;
625 WX_SOCKLEN_T fromlen
= sizeof(from
);
628 DO_WHILE_EINTR( ret
, recvfrom(m_fd
, static_cast<char *>(buffer
), size
,
629 0, &from
.addr
, &fromlen
) );
631 if ( ret
== SOCKET_ERROR
)
634 m_peer
= wxSockAddressImpl(from
.addr
, fromlen
);
635 if ( !m_peer
.IsOk() )
641 int wxSocketImpl::SendDgram(const void *buffer
, int size
)
643 if ( !m_peer
.IsOk() )
645 m_error
= wxSOCKET_INVADDR
;
650 DO_WHILE_EINTR( ret
, sendto(m_fd
, static_cast<const char *>(buffer
), size
,
651 0, m_peer
.GetAddr(), m_peer
.GetLen()) );
656 int wxSocketImpl::Read(void *buffer
, int size
)
658 // server sockets can't be used for IO, only to accept new connections
659 if ( m_fd
== INVALID_SOCKET
|| m_server
)
661 m_error
= wxSOCKET_INVSOCK
;
665 int ret
= m_stream
? RecvStream(buffer
, size
)
666 : RecvDgram(buffer
, size
);
668 m_error
= ret
== SOCKET_ERROR
? GetLastError() : wxSOCKET_NOERROR
;
673 int wxSocketImpl::Write(const void *buffer
, int size
)
675 if ( m_fd
== INVALID_SOCKET
|| m_server
)
677 m_error
= wxSOCKET_INVSOCK
;
681 int ret
= m_stream
? SendStream(buffer
, size
)
682 : SendDgram(buffer
, size
);
684 m_error
= ret
== SOCKET_ERROR
? GetLastError() : wxSOCKET_NOERROR
;
689 // ==========================================================================
691 // ==========================================================================
693 // --------------------------------------------------------------------------
694 // Initialization and shutdown
695 // --------------------------------------------------------------------------
697 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
698 // to m_countInit with a crit section
699 size_t wxSocketBase::m_countInit
= 0;
701 bool wxSocketBase::IsInitialized()
703 return m_countInit
> 0;
706 bool wxSocketBase::Initialize()
708 if ( !m_countInit
++ )
710 wxSocketManager
* const manager
= wxSocketManager::Get();
711 if ( !manager
|| !manager
->OnInit() )
722 void wxSocketBase::Shutdown()
724 // we should be initialized
725 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
726 if ( --m_countInit
== 0 )
728 wxSocketManager
* const manager
= wxSocketManager::Get();
729 wxCHECK_RET( manager
, "should have a socket manager" );
735 // --------------------------------------------------------------------------
737 // --------------------------------------------------------------------------
739 void wxSocketBase::Init()
742 m_type
= wxSOCKET_UNINIT
;
753 m_beingDeleted
= false;
768 if ( !IsInitialized() )
770 // this Initialize() will be undone by wxSocketModule::OnExit(), all
771 // the other calls to it should be matched by a call to Shutdown()
776 wxSocketBase::wxSocketBase()
781 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
790 wxSocketBase::~wxSocketBase()
792 // Just in case the app called Destroy() *and* then deleted the socket
793 // immediately: don't leave dangling pointers.
794 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
796 traits
->RemoveFromPendingDelete(this);
798 // Shutdown and close the socket
802 // Destroy the implementation object
805 // Free the pushback buffer
810 bool wxSocketBase::Destroy()
812 // Delayed destruction: the socket will be deleted during the next idle
813 // loop iteration. This ensures that all pending events have been
815 m_beingDeleted
= true;
817 // Shutdown and close the socket
820 // Suppress events from now on
823 // schedule this object for deletion
824 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
827 // let the traits object decide what to do with us
828 traits
->ScheduleForDestroy(this);
830 else // no app or no traits
832 // in wxBase we might have no app object at all, don't leak memory
839 // ----------------------------------------------------------------------------
841 // ----------------------------------------------------------------------------
843 void wxSocketBase::SetError(wxSocketError error
)
845 m_impl
->m_error
= error
;
848 wxSocketError
wxSocketBase::LastError() const
850 return m_impl
->GetError();
853 // --------------------------------------------------------------------------
855 // --------------------------------------------------------------------------
857 // The following IO operations update m_lcount:
858 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
859 bool wxSocketBase::Close()
861 // Interrupt pending waits
867 m_establishing
= false;
871 void wxSocketBase::ShutdownOutput()
877 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
879 wxSocketReadGuard
read(this);
881 m_lcount
= DoRead(buffer
, nbytes
);
886 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
888 wxCHECK_MSG( m_impl
, 0, "socket must be valid" );
890 // We use pointer arithmetic here which doesn't work with void pointers.
891 char *buffer
= static_cast<char *>(buffer_
);
892 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
894 // Try the push back buffer first, even before checking whether the socket
895 // is valid to allow reading previously pushed back data from an already
897 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
903 // our socket is non-blocking so Read() will return immediately if
904 // there is nothing to read yet and it's more efficient to try it first
905 // before entering DoWait() which is going to start dispatching GUI
906 // events and, even more importantly, we must do this under Windows
907 // where we're not going to get notifications about socket being ready
908 // for reading before we read all the existing data from it
909 const int ret
= m_connected
? m_impl
->Read(buffer
, nbytes
) : 0;
912 if ( m_impl
->GetLastError() == wxSOCKET_WOULDBLOCK
)
914 // if we don't want to wait, just return immediately
915 if ( m_flags
& wxSOCKET_NOWAIT
)
918 // otherwise wait until the socket becomes ready for reading or
919 // an error occurs on it
920 if ( !DoWaitWithTimeout(wxSOCKET_INPUT_FLAG
) )
922 // and exit if the timeout elapsed before it did
923 SetError(wxSOCKET_TIMEDOUT
);
932 SetError(wxSOCKET_IOERR
);
938 // for connection-oriented (e.g. TCP) sockets we can only read
939 // 0 bytes if the other end has been closed, and for connectionless
940 // ones (UDP) this flag doesn't make sense anyhow so we can set it
941 // to true too without doing any harm
944 // we're not going to read anything else and so if we haven't read
945 // anything (or not everything in wxSOCKET_WAITALL case) already,
947 if ( (m_flags
& wxSOCKET_WAITALL
) || !total
)
948 SetError(wxSOCKET_IOERR
);
954 // if we are happy to read something and not the entire nbytes bytes,
956 if ( !(m_flags
& wxSOCKET_WAITALL
) )
966 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
970 unsigned char sig
[4];
971 unsigned char len
[4];
974 wxSocketReadGuard
read(this);
976 wxSocketWaitModeChanger
changeFlags(this, wxSOCKET_WAITALL
);
979 if ( DoRead(&msg
, sizeof(msg
)) == sizeof(msg
) )
981 wxUint32 sig
= (wxUint32
)msg
.sig
[0];
982 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
983 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
984 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
986 if ( sig
== 0xfeeddead )
988 wxUint32 len
= (wxUint32
)msg
.len
[0];
989 len
|= (wxUint32
)(msg
.len
[1] << 8);
990 len
|= (wxUint32
)(msg
.len
[2] << 16);
991 len
|= (wxUint32
)(msg
.len
[3] << 24);
1002 // Don't attempt to read if the msg was zero bytes long.
1003 m_lcount
= len
? DoRead(buffer
, len
) : 0;
1007 char discard_buffer
[MAX_DISCARD_SIZE
];
1010 // NOTE: discarded bytes don't add to m_lcount.
1013 discard_len
= len2
> MAX_DISCARD_SIZE
1016 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
1017 len2
-= (wxUint32
)discard_len
;
1019 while ((discard_len
> 0) && len2
);
1022 if ( !len2
&& DoRead(&msg
, sizeof(msg
)) == sizeof(msg
) )
1024 sig
= (wxUint32
)msg
.sig
[0];
1025 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
1026 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
1027 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
1029 if ( sig
== 0xdeadfeed )
1036 SetError(wxSOCKET_IOERR
);
1041 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
1043 wxSocketReadGuard
read(this);
1045 m_lcount
= DoRead(buffer
, nbytes
);
1047 Pushback(buffer
, m_lcount
);
1052 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
1054 wxSocketWriteGuard
write(this);
1056 m_lcount
= DoWrite(buffer
, nbytes
);
1061 // This function is a mirror image of DoRead() except that it doesn't use the
1062 // push back buffer and doesn't treat 0 return value specially (normally this
1063 // shouldn't happen at all here), so please see comments there for explanations
1064 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
1066 wxCHECK_MSG( m_impl
, 0, "socket must be valid" );
1068 const char *buffer
= static_cast<const char *>(buffer_
);
1069 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1076 if ( (m_flags
& wxSOCKET_WAITALL
) || !total
)
1077 SetError(wxSOCKET_IOERR
);
1081 const int ret
= m_impl
->Write(buffer
, nbytes
);
1084 if ( m_impl
->GetLastError() == wxSOCKET_WOULDBLOCK
)
1086 if ( m_flags
& wxSOCKET_NOWAIT
)
1089 if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG
) )
1091 SetError(wxSOCKET_TIMEDOUT
);
1097 else // "real" error
1099 SetError(wxSOCKET_IOERR
);
1106 if ( !(m_flags
& wxSOCKET_WAITALL
) )
1116 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
1120 unsigned char sig
[4];
1121 unsigned char len
[4];
1124 wxSocketWriteGuard
write(this);
1126 wxSocketWaitModeChanger
changeFlags(this, wxSOCKET_WAITALL
);
1128 msg
.sig
[0] = (unsigned char) 0xad;
1129 msg
.sig
[1] = (unsigned char) 0xde;
1130 msg
.sig
[2] = (unsigned char) 0xed;
1131 msg
.sig
[3] = (unsigned char) 0xfe;
1133 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
1134 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
1135 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
1136 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
1139 if ( DoWrite(&msg
, sizeof(msg
)) == sizeof(msg
) )
1141 m_lcount
= DoWrite(buffer
, nbytes
);
1142 if ( m_lcount
== nbytes
)
1144 msg
.sig
[0] = (unsigned char) 0xed;
1145 msg
.sig
[1] = (unsigned char) 0xfe;
1146 msg
.sig
[2] = (unsigned char) 0xad;
1147 msg
.sig
[3] = (unsigned char) 0xde;
1151 msg
.len
[3] = (char) 0;
1153 if ( DoWrite(&msg
, sizeof(msg
)) == sizeof(msg
))
1159 SetError(wxSOCKET_IOERR
);
1164 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
1167 Pushback(buffer
, nbytes
);
1169 SetError(wxSOCKET_NOERROR
);
1175 wxSocketBase
& wxSocketBase::Discard()
1177 char *buffer
= new char[MAX_DISCARD_SIZE
];
1181 wxSocketReadGuard
read(this);
1183 wxSocketWaitModeChanger
changeFlags(this, wxSOCKET_NOWAIT
);
1187 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
1190 while (ret
== MAX_DISCARD_SIZE
);
1194 SetError(wxSOCKET_NOERROR
);
1199 // --------------------------------------------------------------------------
1201 // --------------------------------------------------------------------------
1204 This function will check for the events specified in the flags parameter,
1205 and it will return a mask indicating which operations can be performed.
1207 wxSocketEventFlags
wxSocketImpl::Select(wxSocketEventFlags flags
,
1208 const timeval
*timeout
)
1210 if ( m_fd
== INVALID_SOCKET
)
1211 return (wxSOCKET_LOST_FLAG
& flags
);
1217 tv
.tv_sec
= tv
.tv_usec
= 0;
1219 // prepare the FD sets, passing NULL for the one(s) we don't use
1221 readfds
, *preadfds
= NULL
,
1222 writefds
, *pwritefds
= NULL
,
1223 exceptfds
; // always want to know about errors
1225 if ( flags
& wxSOCKET_INPUT_FLAG
)
1227 preadfds
= &readfds
;
1228 wxFD_ZERO(preadfds
);
1229 wxFD_SET(m_fd
, preadfds
);
1232 // when using non-blocking connect() the socket becomes connected
1233 // (successfully or not) when it becomes writable
1234 if ( flags
& (wxSOCKET_OUTPUT_FLAG
| wxSOCKET_CONNECTION_FLAG
) )
1236 pwritefds
= &writefds
;
1237 wxFD_ZERO(pwritefds
);
1238 wxFD_SET(m_fd
, pwritefds
);
1241 wxFD_ZERO(&exceptfds
);
1242 wxFD_SET(m_fd
, &exceptfds
);
1244 const int rc
= select(m_fd
+ 1, preadfds
, pwritefds
, &exceptfds
, &tv
);
1246 // check for errors first
1247 if ( rc
== -1 || wxFD_ISSET(m_fd
, &exceptfds
) )
1249 m_establishing
= false;
1251 return wxSOCKET_LOST_FLAG
& flags
;
1257 wxASSERT_MSG( rc
== 1, "unexpected select() return value" );
1259 wxSocketEventFlags detected
= 0;
1260 if ( preadfds
&& wxFD_ISSET(m_fd
, preadfds
) )
1261 detected
|= wxSOCKET_INPUT_FLAG
;
1263 if ( pwritefds
&& wxFD_ISSET(m_fd
, pwritefds
) )
1265 // check for the case of non-blocking connect()
1266 if ( m_establishing
&& !m_server
)
1269 SOCKOPTLEN_T len
= sizeof(error
);
1270 m_establishing
= false;
1271 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1274 detected
= wxSOCKET_LOST_FLAG
;
1276 detected
|= wxSOCKET_CONNECTION_FLAG
;
1278 else // not called to get non-blocking connect() status
1280 detected
|= wxSOCKET_OUTPUT_FLAG
;
1284 return detected
& flags
;
1288 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1290 // Use either the provided timeout or the default timeout value associated
1291 // with this socket.
1293 // TODO: allow waiting forever, see #9443
1294 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1295 : seconds
* 1000 + milliseconds
;
1297 return DoWait(timeout
, flags
);
1301 wxSocketBase::DoWait(long timeout
, wxSocketEventFlags flags
)
1303 wxCHECK_MSG( m_impl
, -1, "can't wait on invalid socket" );
1305 // we're never going to become ready if we're not connected (any more)
1306 if ( !m_connected
&& !m_establishing
)
1309 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1310 m_interrupt
= false;
1313 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1315 // Get the active event loop which we'll use for the message dispatching
1316 // when running in the main thread unless this was explicitly disabled by
1317 // setting wxSOCKET_BLOCK flag
1318 wxEventLoopBase
*eventLoop
;
1319 if ( !(m_flags
& wxSOCKET_BLOCK
) && wxIsMainThread() )
1321 eventLoop
= wxEventLoop::GetActive();
1323 else // in worker thread
1325 // We never dispatch messages from threads other than the main one.
1329 // Wait until we receive the event we're waiting for or the timeout expires
1330 // (but note that we always execute the loop at least once, even if timeout
1331 // is 0 as this is used for polling)
1333 for ( bool firstTime
= true; !m_interrupt
; firstTime
= false )
1335 long timeLeft
= wxMilliClockToLong(timeEnd
- wxGetLocalTimeMillis());
1344 wxSocketEventFlags events
;
1347 // reset them before starting to wait
1350 eventLoop
->DispatchTimeout(timeLeft
);
1352 events
= m_eventsgot
;
1354 else // no event loop or waiting in another thread
1356 // as explained below, we should always check for wxSOCKET_LOST_FLAG
1358 SetTimeValFromMS(tv
, timeLeft
);
1359 events
= m_impl
->Select(flags
| wxSOCKET_LOST_FLAG
, &tv
);
1362 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1363 // it, as continuing to wait for anything else after getting it is
1365 if ( events
& wxSOCKET_LOST_FLAG
)
1367 m_connected
= false;
1368 m_establishing
= false;
1373 // otherwise mask out the bits we're not interested in
1376 // Incoming connection (server) or connection established (client)?
1377 if ( events
& wxSOCKET_CONNECTION_FLAG
)
1380 m_establishing
= false;
1385 // Data available or output buffer ready?
1386 if ( (events
& wxSOCKET_INPUT_FLAG
) || (events
& wxSOCKET_OUTPUT_FLAG
) )
1396 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1398 return DoWait(seconds
, milliseconds
,
1399 wxSOCKET_INPUT_FLAG
|
1400 wxSOCKET_OUTPUT_FLAG
|
1401 wxSOCKET_CONNECTION_FLAG
) != 0;
1404 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1406 // Check pushback buffer before entering DoWait
1410 // Check if the socket is not already ready for input, if it is, there is
1411 // no need to start waiting for it (worse, we'll actually never get a
1412 // notification about the socket becoming ready if it is already under
1414 if ( m_impl
->Select(wxSOCKET_INPUT_FLAG
) )
1417 return DoWait(seconds
, milliseconds
, wxSOCKET_INPUT_FLAG
) != 0;
1421 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1423 if ( m_impl
->Select(wxSOCKET_OUTPUT_FLAG
) )
1426 return DoWait(seconds
, milliseconds
, wxSOCKET_OUTPUT_FLAG
) != 0;
1429 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1431 return DoWait(seconds
, milliseconds
, wxSOCKET_LOST_FLAG
) == -1;
1434 // --------------------------------------------------------------------------
1436 // --------------------------------------------------------------------------
1439 // Get local or peer address
1442 bool wxSocketBase::GetPeer(wxSockAddress
& addr
) const
1444 wxCHECK_MSG( m_impl
, false, "invalid socket" );
1446 const wxSockAddressImpl
& peer
= m_impl
->GetPeer();
1450 addr
.SetAddress(peer
);
1455 bool wxSocketBase::GetLocal(wxSockAddress
& addr
) const
1457 wxCHECK_MSG( m_impl
, false, "invalid socket" );
1459 const wxSockAddressImpl
& local
= m_impl
->GetLocal();
1460 if ( !local
.IsOk() )
1463 addr
.SetAddress(local
);
1469 // Save and restore socket state
1472 void wxSocketBase::SaveState()
1474 wxSocketState
*state
;
1476 state
= new wxSocketState();
1478 state
->m_flags
= m_flags
;
1479 state
->m_notify
= m_notify
;
1480 state
->m_eventmask
= m_eventmask
;
1481 state
->m_clientData
= m_clientData
;
1483 m_states
.Append(state
);
1486 void wxSocketBase::RestoreState()
1488 wxList::compatibility_iterator node
;
1489 wxSocketState
*state
;
1491 node
= m_states
.GetLast();
1495 state
= (wxSocketState
*)node
->GetData();
1497 m_flags
= state
->m_flags
;
1498 m_notify
= state
->m_notify
;
1499 m_eventmask
= state
->m_eventmask
;
1500 m_clientData
= state
->m_clientData
;
1502 m_states
.Erase(node
);
1507 // Timeout and flags
1510 void wxSocketBase::SetTimeout(long seconds
)
1512 m_timeout
= seconds
;
1515 m_impl
->SetTimeout(m_timeout
* 1000);
1518 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1520 // Do some sanity checking on the flags used: not all values can be used
1522 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1523 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1524 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1525 "wxSOCKET_NOWAIT doesn't make sense" );
1531 // --------------------------------------------------------------------------
1533 // --------------------------------------------------------------------------
1535 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1537 wxSocketEventFlags flag
= 0;
1538 switch ( notification
)
1540 case wxSOCKET_INPUT
:
1541 flag
= wxSOCKET_INPUT_FLAG
;
1544 case wxSOCKET_OUTPUT
:
1545 flag
= wxSOCKET_OUTPUT_FLAG
;
1548 case wxSOCKET_CONNECTION
:
1549 flag
= wxSOCKET_CONNECTION_FLAG
;
1553 flag
= wxSOCKET_LOST_FLAG
;
1557 wxFAIL_MSG( "unknown wxSocket notification" );
1560 // if we lost the connection the socket is now closed
1561 if ( notification
== wxSOCKET_LOST
)
1564 // remember the events which were generated for this socket, we're going to
1565 // use this in DoWait()
1566 m_eventsgot
|= flag
;
1568 // send the wx event if enabled and we're interested in it
1569 if ( m_notify
&& (m_eventmask
& flag
) && m_handler
)
1571 // don't generate the events when we're inside DoWait() called from our
1572 // own code as we are going to consume the data that has just become
1573 // available ourselves and the user code won't see it at all
1574 if ( (notification
== wxSOCKET_INPUT
&& m_reading
) ||
1575 (notification
== wxSOCKET_OUTPUT
&& m_writing
) )
1580 wxSocketEvent
event(m_id
);
1581 event
.m_event
= notification
;
1582 event
.m_clientData
= m_clientData
;
1583 event
.SetEventObject(this);
1585 m_handler
->AddPendingEvent(event
);
1589 void wxSocketBase::Notify(bool notify
)
1594 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1596 m_eventmask
= flags
;
1599 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1601 m_handler
= &handler
;
1605 // --------------------------------------------------------------------------
1607 // --------------------------------------------------------------------------
1609 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1613 if (m_unread
== NULL
)
1614 m_unread
= malloc(size
);
1619 tmp
= malloc(m_unrd_size
+ size
);
1620 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1626 m_unrd_size
+= size
;
1628 memcpy(m_unread
, buffer
, size
);
1631 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1633 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1638 if (size
> (m_unrd_size
-m_unrd_cur
))
1639 size
= m_unrd_size
-m_unrd_cur
;
1641 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1646 if (m_unrd_size
== m_unrd_cur
)
1659 // ==========================================================================
1661 // ==========================================================================
1663 // --------------------------------------------------------------------------
1665 // --------------------------------------------------------------------------
1667 wxSocketServer::wxSocketServer(const wxSockAddress
& addr
,
1668 wxSocketFlags flags
)
1669 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1671 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1673 m_impl
= wxSocketImpl::Create(*this);
1677 wxLogTrace( wxTRACE_Socket
, _T("*** Failed to create m_impl") );
1681 // Setup the socket as server
1682 m_impl
->SetLocal(addr
.GetAddress());
1684 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1685 m_impl
->SetReusable();
1687 if (GetFlags() & wxSOCKET_BROADCAST
) {
1688 m_impl
->SetBroadcast();
1690 if (GetFlags() & wxSOCKET_NOBIND
) {
1691 m_impl
->DontDoBind();
1694 if (m_impl
->CreateServer() != wxSOCKET_NOERROR
)
1699 wxLogTrace( wxTRACE_Socket
, _T("*** CreateServer() failed") );
1703 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_impl
->m_fd
);
1706 // --------------------------------------------------------------------------
1708 // --------------------------------------------------------------------------
1710 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1712 if ( !m_impl
|| (m_impl
->m_fd
== INVALID_SOCKET
) || !m_impl
->IsServer() )
1714 wxFAIL_MSG( "can only be called for a valid server socket" );
1716 SetError(wxSOCKET_INVSOCK
);
1723 // wait until we get a connection
1724 if ( !m_impl
->SelectWithTimeout(wxSOCKET_INPUT_FLAG
) )
1726 SetError(wxSOCKET_TIMEDOUT
);
1732 sock
.m_impl
= m_impl
->Accept(sock
);
1736 SetError(m_impl
->GetLastError());
1741 sock
.m_type
= wxSOCKET_BASE
;
1742 sock
.m_connected
= true;
1747 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1749 wxSocketBase
* sock
= new wxSocketBase();
1751 sock
->SetFlags(m_flags
);
1753 if (!AcceptWith(*sock
, wait
))
1762 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1764 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
) == 1;
1767 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1769 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1771 SOCKOPTLEN_T lenreal
= *optlen
;
1772 if ( getsockopt(m_impl
->m_fd
, level
, optname
,
1773 static_cast<char *>(optval
), &lenreal
) != 0 )
1782 wxSocketBase::SetOption(int level
, int optname
, const void *optval
, int optlen
)
1784 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1786 return setsockopt(m_impl
->m_fd
, level
, optname
,
1787 static_cast<const char *>(optval
), optlen
) == 0;
1790 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1792 m_localAddress
= local
;
1797 // ==========================================================================
1799 // ==========================================================================
1801 // --------------------------------------------------------------------------
1803 // --------------------------------------------------------------------------
1805 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1806 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1808 m_initialRecvBufferSize
=
1809 m_initialSendBufferSize
= -1;
1812 // --------------------------------------------------------------------------
1814 // --------------------------------------------------------------------------
1816 bool wxSocketClient::DoConnect(const wxSockAddress
& remote
,
1817 const wxSockAddress
* local
,
1822 // Shutdown and destroy the old socket
1827 m_connected
= false;
1828 m_establishing
= false;
1830 // Create and set up the new one
1831 m_impl
= wxSocketImpl::Create(*this);
1835 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1836 if (GetFlags() & wxSOCKET_REUSEADDR
)
1837 m_impl
->SetReusable();
1838 if (GetFlags() & wxSOCKET_BROADCAST
)
1839 m_impl
->SetBroadcast();
1840 if (GetFlags() & wxSOCKET_NOBIND
)
1841 m_impl
->DontDoBind();
1843 // Bind to the local IP address and port, when provided or if one had been
1845 if ( !local
&& m_localAddress
.GetAddress().IsOk() )
1846 local
= &m_localAddress
;
1849 m_impl
->SetLocal(local
->GetAddress());
1851 m_impl
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1853 m_impl
->SetPeer(remote
.GetAddress());
1855 // Finally do create the socket and connect to the peer
1856 const wxSocketError err
= m_impl
->CreateClient(wait
);
1858 if ( err
!= wxSOCKET_NOERROR
)
1860 if ( err
== wxSOCKET_WOULDBLOCK
)
1862 wxASSERT_MSG( !wait
, "shouldn't get this for blocking connect" );
1864 m_establishing
= true;
1874 bool wxSocketClient::Connect(const wxSockAddress
& remote
, bool wait
)
1876 return DoConnect(remote
, NULL
, wait
);
1879 bool wxSocketClient::Connect(const wxSockAddress
& remote
,
1880 const wxSockAddress
& local
,
1883 return DoConnect(remote
, &local
, wait
);
1886 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1890 // this happens if the initial attempt to connect succeeded without
1895 wxCHECK_MSG( m_establishing
&& m_impl
, false,
1896 "No connection establishment attempt in progress" );
1898 // notice that we return true even if DoWait() returned -1, i.e. if an
1899 // error occurred and connection was lost: this is intentional as we should
1900 // return false only if timeout expired without anything happening
1901 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
) != 0;
1904 // ==========================================================================
1906 // ==========================================================================
1908 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1909 wxSocketFlags flags
)
1910 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1912 // Create the socket
1913 m_impl
= wxSocketImpl::Create(*this);
1918 // Setup the socket as non connection oriented
1919 m_impl
->SetLocal(addr
.GetAddress());
1920 if (flags
& wxSOCKET_REUSEADDR
)
1922 m_impl
->SetReusable();
1924 if (GetFlags() & wxSOCKET_BROADCAST
)
1926 m_impl
->SetBroadcast();
1928 if (GetFlags() & wxSOCKET_NOBIND
)
1930 m_impl
->DontDoBind();
1933 if ( m_impl
->CreateUDP() != wxSOCKET_NOERROR
)
1940 // Initialize all stuff
1941 m_connected
= false;
1942 m_establishing
= false;
1945 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1954 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1958 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1960 m_impl
->SetPeer(addr
.GetAddress());
1965 // ==========================================================================
1967 // ==========================================================================
1969 class wxSocketModule
: public wxModule
1972 virtual bool OnInit()
1974 // wxSocketBase will call Initialize() itself only if sockets are
1975 // really used, don't do it from here
1979 virtual void OnExit()
1981 if ( wxSocketBase::IsInitialized() )
1982 wxSocketBase::Shutdown();
1986 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1989 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1991 #endif // wxUSE_SOCKETS