1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/socket.cpp
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
6 // Copyright: (C) 1999-1997, Guilhem Lavaux
7 // (C) 1999-2000, Guillermo Rodriguez Garcia
8 // (C) 2008 Vadim Zeitlin
10 // License: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
13 // ==========================================================================
15 // ==========================================================================
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
26 #include "wx/socket.h"
29 #include "wx/object.h"
30 #include "wx/string.h"
37 #include "wx/module.h"
40 #include "wx/apptrait.h"
41 #include "wx/sckaddr.h"
42 #include "wx/stopwatch.h"
43 #include "wx/thread.h"
44 #include "wx/evtloop.h"
46 #include "wx/private/fd.h"
47 #include "wx/private/socket.h"
49 // DLL options compatibility check:
51 WX_CHECK_BUILD_OPTIONS("wxNet")
53 // --------------------------------------------------------------------------
54 // macros and constants
55 // --------------------------------------------------------------------------
58 #define MAX_DISCARD_SIZE (10 * 1024)
60 #define wxTRACE_Socket _T("wxSocket")
62 // --------------------------------------------------------------------------
64 // --------------------------------------------------------------------------
66 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
67 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
68 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
69 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
70 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
72 // ----------------------------------------------------------------------------
74 // ----------------------------------------------------------------------------
79 void SetTimeValFromMS(timeval
& tv
, unsigned long ms
)
81 tv
.tv_sec
= (ms
/ 1000);
82 tv
.tv_usec
= (ms
% 1000) * 1000;
85 } // anonymous namespace
87 // --------------------------------------------------------------------------
89 // --------------------------------------------------------------------------
91 class wxSocketState
: public wxObject
94 wxSocketFlags m_flags
;
95 wxSocketEventFlags m_eventmask
;
100 wxSocketState() : wxObject() {}
102 DECLARE_NO_COPY_CLASS(wxSocketState
)
105 // ============================================================================
107 // ============================================================================
109 wxSocketManager
*wxSocketManager::ms_manager
= NULL
;
112 void wxSocketManager::Set(wxSocketManager
*manager
)
114 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
116 ms_manager
= manager
;
120 void wxSocketManager::Init()
122 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
125 Details: Initialize() creates a hidden window as a sink for socket
126 events, such as 'read completed'. wxMSW has only one message loop
127 for the main thread. If Initialize is called in a secondary thread,
128 the socket window will be created for the secondary thread, but
129 since there is no message loop on this thread, it will never
130 receive events and all socket operations will time out.
131 BTW, the main thread must not be stopped using sleep or block
132 on a semaphore (a bad idea in any case) or socket operations
135 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
136 the main thread. Because secondary threads do not have run loops,
137 adding event notifications to the "Current" loop would have no
138 effect at all, events would never fire.
140 wxASSERT_MSG( wxIsMainThread(),
141 "sockets must be initialized from the main thread" );
143 wxAppConsole
* const app
= wxAppConsole::GetInstance();
144 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
146 ms_manager
= app
->GetTraits()->GetSocketManager();
149 // ==========================================================================
151 // ==========================================================================
153 wxSocketImpl::wxSocketImpl(wxSocketBase
& wxsocket
)
154 : m_wxsocket(&wxsocket
)
156 m_fd
= INVALID_SOCKET
;
160 m_error
= wxSOCKET_NOERROR
;
164 SetTimeout(wxsocket
.GetTimeout() * 1000);
166 m_establishing
= false;
170 m_initialRecvBufferSize
= -1;
171 m_initialSendBufferSize
= -1;
174 wxSocketImpl::~wxSocketImpl()
176 if (m_fd
!= INVALID_SOCKET
)
180 GAddress_destroy(m_local
);
183 GAddress_destroy(m_peer
);
186 bool wxSocketImpl::PreCreateCheck(GAddress
*addr
)
188 if ( m_fd
!= INVALID_SOCKET
)
190 m_error
= wxSOCKET_INVSOCK
;
194 if ( !addr
|| !addr
->m_addr
)
196 m_error
= wxSOCKET_INVADDR
;
203 void wxSocketImpl::PostCreation()
205 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
207 EnableSocketOption(SO_NOSIGPIPE
);
211 EnableSocketOption(SO_REUSEADDR
);
215 wxASSERT_MSG( !m_stream
, "broadcasting is for datagram sockets only" );
217 EnableSocketOption(SO_BROADCAST
);
220 if ( m_initialRecvBufferSize
>= 0 )
221 SetSocketOption(SO_RCVBUF
, m_initialRecvBufferSize
);
222 if ( m_initialSendBufferSize
>= 0 )
223 SetSocketOption(SO_SNDBUF
, m_initialSendBufferSize
);
225 // we always put our sockets in unblocked mode and handle blocking
226 // ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
227 UnblockAndRegisterWithEventLoop();
230 wxSocketError
wxSocketImpl::UpdateLocalAddress()
232 WX_SOCKLEN_T lenAddr
= sizeof(*m_local
->m_addr
);
233 if ( getsockname(m_fd
, m_local
->m_addr
, &lenAddr
) != 0 )
236 m_error
= wxSOCKET_IOERR
;
240 m_local
->m_len
= lenAddr
;
242 return wxSOCKET_NOERROR
;
245 wxSocketError
wxSocketImpl::CreateServer()
247 if ( !PreCreateCheck(m_local
) )
253 // do create the socket
254 m_fd
= socket(m_local
->m_realfamily
, SOCK_STREAM
, 0);
256 if ( m_fd
== INVALID_SOCKET
)
258 m_error
= wxSOCKET_IOERR
;
259 return wxSOCKET_IOERR
;
264 // and then bind to and listen on it
266 // FIXME: should we test for m_dobind here?
267 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
268 m_error
= wxSOCKET_IOERR
;
272 if ( listen(m_fd
, 5) != 0 )
273 m_error
= wxSOCKET_IOERR
;
282 // finally retrieve the address we effectively bound to
283 return UpdateLocalAddress();
286 wxSocketError
wxSocketImpl::CreateClient(bool wait
)
288 if ( !PreCreateCheck(m_peer
) )
291 m_fd
= socket(m_peer
->m_realfamily
, SOCK_STREAM
, 0);
293 if ( m_fd
== INVALID_SOCKET
)
295 m_error
= wxSOCKET_IOERR
;
296 return wxSOCKET_IOERR
;
301 // If a local address has been set, then bind to it before calling connect
302 if ( m_local
&& m_local
->m_addr
)
304 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
307 m_error
= wxSOCKET_IOERR
;
313 int rc
= connect(m_fd
, m_peer
->m_addr
, m_peer
->m_len
);
314 if ( rc
== SOCKET_ERROR
)
316 wxSocketError err
= GetLastError();
317 if ( err
== wxSOCKET_WOULDBLOCK
)
319 m_establishing
= true;
321 // block waiting for connection if we should (otherwise just return
322 // wxSOCKET_WOULDBLOCK to the caller)
325 err
= SelectWithTimeout(wxSOCKET_CONNECTION_FLAG
)
328 m_establishing
= false;
336 m_error
= wxSOCKET_NOERROR
;
343 wxSocketError
wxSocketImpl::CreateUDP()
345 if ( !PreCreateCheck(m_local
) )
351 m_fd
= socket(m_local
->m_realfamily
, SOCK_DGRAM
, 0);
353 if ( m_fd
== INVALID_SOCKET
)
355 m_error
= wxSOCKET_IOERR
;
356 return wxSOCKET_IOERR
;
363 if ( bind(m_fd
, m_local
->m_addr
, m_local
->m_len
) != 0 )
366 m_error
= wxSOCKET_IOERR
;
370 return UpdateLocalAddress();
373 return wxSOCKET_NOERROR
;
376 wxSocketImpl
*wxSocketImpl::Accept(wxSocketBase
& wxsocket
)
379 WX_SOCKLEN_T fromlen
= sizeof(from
);
380 const int fd
= accept(m_fd
, &from
, &fromlen
);
382 if ( fd
== INVALID_SOCKET
)
385 wxSocketImpl
* const sock
= Create(wxsocket
);
388 sock
->m_peer
= GAddress_new();
389 _GAddress_translate_from(sock
->m_peer
, &from
, fromlen
);
391 sock
->UnblockAndRegisterWithEventLoop();
397 void wxSocketImpl::Close()
399 if ( m_fd
!= INVALID_SOCKET
)
402 m_fd
= INVALID_SOCKET
;
407 * Disallow further read/write operations on this socket, close
408 * the fd and disable all callbacks.
410 void wxSocketImpl::Shutdown()
412 if ( m_fd
!= INVALID_SOCKET
)
414 shutdown(m_fd
, 1 /* SD_SEND */);
418 m_detected
= wxSOCKET_LOST_FLAG
;
422 * Sets the timeout for blocking calls. Time is expressed in
425 void wxSocketImpl::SetTimeout(unsigned long millis
)
427 SetTimeValFromMS(m_timeout
, millis
);
430 void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event
)
432 m_wxsocket
->OnRequest(event
);
435 /* Address handling */
438 * Set or get the local or peer address for this socket. The 'set'
439 * functions return wxSOCKET_NOERROR on success, an error code otherwise.
440 * The 'get' functions return a pointer to a GAddress object on success,
441 * or NULL otherwise, in which case they set the error code of the
442 * corresponding socket.
445 * wxSOCKET_INVSOCK - the socket is not valid.
446 * wxSOCKET_INVADDR - the address is not valid.
448 wxSocketError
wxSocketImpl::SetLocal(GAddress
*address
)
450 /* the socket must be initialized, or it must be a server */
451 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
453 m_error
= wxSOCKET_INVSOCK
;
454 return wxSOCKET_INVSOCK
;
458 if (address
== NULL
|| address
->m_family
== wxSOCKET_NOFAMILY
)
460 m_error
= wxSOCKET_INVADDR
;
461 return wxSOCKET_INVADDR
;
465 GAddress_destroy(m_local
);
467 m_local
= GAddress_copy(address
);
469 return wxSOCKET_NOERROR
;
472 wxSocketError
wxSocketImpl::SetPeer(GAddress
*address
)
475 if (address
== NULL
|| address
->m_family
== wxSOCKET_NOFAMILY
)
477 m_error
= wxSOCKET_INVADDR
;
478 return wxSOCKET_INVADDR
;
482 GAddress_destroy(m_peer
);
484 m_peer
= GAddress_copy(address
);
486 return wxSOCKET_NOERROR
;
489 GAddress
*wxSocketImpl::GetLocal()
493 WX_SOCKLEN_T size
= sizeof(addr
);
496 /* try to get it from the m_local var first */
498 return GAddress_copy(m_local
);
500 /* else, if the socket is initialized, try getsockname */
501 if (m_fd
== INVALID_SOCKET
)
503 m_error
= wxSOCKET_INVSOCK
;
507 if (getsockname(m_fd
, (sockaddr
*)&addr
, &size
) == SOCKET_ERROR
)
509 m_error
= wxSOCKET_IOERR
;
513 /* got a valid address from getsockname, create a GAddress object */
514 if ((address
= GAddress_new()) == NULL
)
516 m_error
= wxSOCKET_MEMERR
;
520 if ((err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
)) != wxSOCKET_NOERROR
)
522 GAddress_destroy(address
);
530 GAddress
*wxSocketImpl::GetPeer()
532 /* try to get it from the m_peer var */
534 return GAddress_copy(m_peer
);
539 // ==========================================================================
541 // ==========================================================================
543 // --------------------------------------------------------------------------
544 // Initialization and shutdown
545 // --------------------------------------------------------------------------
547 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
548 // to m_countInit with a crit section
549 size_t wxSocketBase::m_countInit
= 0;
551 bool wxSocketBase::IsInitialized()
553 return m_countInit
> 0;
556 bool wxSocketBase::Initialize()
558 if ( !m_countInit
++ )
560 wxSocketManager
* const manager
= wxSocketManager::Get();
561 if ( !manager
|| !manager
->OnInit() )
572 void wxSocketBase::Shutdown()
574 // we should be initialized
575 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
576 if ( --m_countInit
== 0 )
578 wxSocketManager
* const manager
= wxSocketManager::Get();
579 wxCHECK_RET( manager
, "should have a socket manager" );
585 // --------------------------------------------------------------------------
587 // --------------------------------------------------------------------------
589 void wxSocketBase::Init()
592 m_type
= wxSOCKET_UNINIT
;
603 m_beingDeleted
= false;
618 if ( !IsInitialized() )
620 // this Initialize() will be undone by wxSocketModule::OnExit(), all
621 // the other calls to it should be matched by a call to Shutdown()
626 wxSocketBase::wxSocketBase()
631 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
640 wxSocketBase::~wxSocketBase()
642 // Just in case the app called Destroy() *and* then deleted the socket
643 // immediately: don't leave dangling pointers.
644 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
646 traits
->RemoveFromPendingDelete(this);
648 // Shutdown and close the socket
652 // Destroy the implementation object
655 // Free the pushback buffer
660 bool wxSocketBase::Destroy()
662 // Delayed destruction: the socket will be deleted during the next idle
663 // loop iteration. This ensures that all pending events have been
665 m_beingDeleted
= true;
667 // Shutdown and close the socket
670 // Suppress events from now on
673 // schedule this object for deletion
674 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
677 // let the traits object decide what to do with us
678 traits
->ScheduleForDestroy(this);
680 else // no app or no traits
682 // in wxBase we might have no app object at all, don't leak memory
689 // ----------------------------------------------------------------------------
691 // ----------------------------------------------------------------------------
693 void wxSocketBase::SetError(wxSocketError error
)
695 m_impl
->m_error
= error
;
698 wxSocketError
wxSocketBase::LastError() const
700 return m_impl
->GetError();
703 // --------------------------------------------------------------------------
705 // --------------------------------------------------------------------------
707 // The following IO operations update m_lcount:
708 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
709 bool wxSocketBase::Close()
711 // Interrupt pending waits
718 m_establishing
= false;
722 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
727 m_lcount
= DoRead(buffer
, nbytes
);
729 // Allow read events from now on
735 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
737 // We use pointer arithmetic here which doesn't work with void pointers.
738 char *buffer
= static_cast<char *>(buffer_
);
740 // Try the push back buffer first, even before checking whether the socket
741 // is valid to allow reading previously pushed back data from an already
743 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
747 // If it's indeed closed or if read everything, there is nothing more to do.
748 if ( !m_impl
|| !nbytes
)
751 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
754 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
755 // polling the socket and don't block at all.
756 if ( m_flags
& wxSOCKET_NOWAIT
)
758 int ret
= m_impl
->Read(buffer
, nbytes
);
761 if ( m_impl
->GetLastError() != wxSOCKET_WOULDBLOCK
)
762 SetError(wxSOCKET_IOERR
);
764 else // not an error, even if we didn't read anything
769 else // blocking socket
773 // Wait until socket becomes ready for reading
774 if ( !WaitForRead() )
777 const int ret
= m_impl
->Read(buffer
, nbytes
);
780 // for connection-oriented (e.g. TCP) sockets we can only read
781 // 0 bytes if the other end has been closed, and for
782 // connectionless ones (UDP) this flag doesn't make sense
783 // anyhow so we can set it to true too without doing any harm
790 SetError(wxSOCKET_IOERR
);
796 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
797 // something and we don't need to wait for all nbytes bytes to be
799 if ( !(m_flags
& wxSOCKET_WAITALL
) )
802 // Otherwise continue reading until we do read everything.
810 // it's an error to not read everything in wxSOCKET_WAITALL mode or to
811 // not read anything otherwise
812 if ( ((m_flags
& wxSOCKET_WAITALL
) && nbytes
) || !total
)
813 SetError(wxSOCKET_IOERR
);
819 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
823 unsigned char sig
[4];
824 unsigned char len
[4];
830 int old_flags
= m_flags
;
831 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
834 if ( DoRead(&msg
, sizeof(msg
)) == sizeof(msg
) )
836 wxUint32 sig
= (wxUint32
)msg
.sig
[0];
837 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
838 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
839 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
841 if ( sig
== 0xfeeddead )
843 wxUint32 len
= (wxUint32
)msg
.len
[0];
844 len
|= (wxUint32
)(msg
.len
[1] << 8);
845 len
|= (wxUint32
)(msg
.len
[2] << 16);
846 len
|= (wxUint32
)(msg
.len
[3] << 24);
857 // Don't attempt to read if the msg was zero bytes long.
858 m_lcount
= len
? DoRead(buffer
, len
) : 0;
862 char discard_buffer
[MAX_DISCARD_SIZE
];
865 // NOTE: discarded bytes don't add to m_lcount.
868 discard_len
= len2
> MAX_DISCARD_SIZE
871 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
872 len2
-= (wxUint32
)discard_len
;
874 while ((discard_len
> 0) && len2
);
877 if ( !len2
&& DoRead(&msg
, sizeof(msg
)) == sizeof(msg
) )
879 sig
= (wxUint32
)msg
.sig
[0];
880 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
881 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
882 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
884 if ( sig
== 0xdeadfeed )
891 SetError(wxSOCKET_IOERR
);
899 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
904 m_lcount
= DoRead(buffer
, nbytes
);
905 Pushback(buffer
, m_lcount
);
907 // Allow read events again
913 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
918 m_lcount
= DoWrite(buffer
, nbytes
);
920 // Allow write events again
926 // This function is a mirror image of DoRead() except that it doesn't use the
927 // push back buffer, please see comments there
928 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
930 const char *buffer
= static_cast<const char *>(buffer_
);
932 // Return if there is nothing to read or the socket is (already?) closed.
933 if ( !m_impl
|| !nbytes
)
936 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
939 if ( m_flags
& wxSOCKET_NOWAIT
)
941 const int ret
= m_impl
->Write(buffer
, nbytes
);
944 if ( m_impl
->GetLastError() != wxSOCKET_WOULDBLOCK
)
945 SetError(wxSOCKET_IOERR
);
952 else // blocking socket
956 if ( !WaitForWrite() )
959 const int ret
= m_impl
->Write(buffer
, nbytes
);
968 SetError(wxSOCKET_IOERR
);
973 if ( !(m_flags
& wxSOCKET_WAITALL
) )
983 if ( ((m_flags
& wxSOCKET_WAITALL
) && nbytes
) || !total
)
984 SetError(wxSOCKET_IOERR
);
990 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
994 unsigned char sig
[4];
995 unsigned char len
[4];
1001 const int old_flags
= m_flags
;
1002 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
1004 msg
.sig
[0] = (unsigned char) 0xad;
1005 msg
.sig
[1] = (unsigned char) 0xde;
1006 msg
.sig
[2] = (unsigned char) 0xed;
1007 msg
.sig
[3] = (unsigned char) 0xfe;
1009 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
1010 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
1011 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
1012 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
1015 if ( DoWrite(&msg
, sizeof(msg
)) == sizeof(msg
) )
1017 m_lcount
= DoWrite(buffer
, nbytes
);
1018 if ( m_lcount
== nbytes
)
1020 msg
.sig
[0] = (unsigned char) 0xed;
1021 msg
.sig
[1] = (unsigned char) 0xfe;
1022 msg
.sig
[2] = (unsigned char) 0xad;
1023 msg
.sig
[3] = (unsigned char) 0xde;
1027 msg
.len
[3] = (char) 0;
1029 if ( DoWrite(&msg
, sizeof(msg
)) == sizeof(msg
))
1035 SetError(wxSOCKET_IOERR
);
1038 SetFlags(old_flags
);
1043 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
1046 Pushback(buffer
, nbytes
);
1048 SetError(wxSOCKET_NOERROR
);
1054 wxSocketBase
& wxSocketBase::Discard()
1056 char *buffer
= new char[MAX_DISCARD_SIZE
];
1063 const int old_flags
= m_flags
;
1064 SetFlags(wxSOCKET_NOWAIT
);
1068 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
1071 while (ret
== MAX_DISCARD_SIZE
);
1075 SetError(wxSOCKET_NOERROR
);
1077 // Allow read events again
1080 SetFlags(old_flags
);
1085 // --------------------------------------------------------------------------
1087 // --------------------------------------------------------------------------
1090 This function will check for the events specified in the flags parameter,
1091 and it will return a mask indicating which operations can be performed.
1093 wxSocketEventFlags
wxSocketImpl::Select(wxSocketEventFlags flags
,
1094 const timeval
*timeout
)
1096 wxSocketEventFlags result
= 0;
1098 if (m_fd
== INVALID_SOCKET
)
1099 return (wxSOCKET_LOST_FLAG
& flags
);
1105 tv
.tv_sec
= tv
.tv_usec
= 0;
1110 wxFD_ZERO(&readfds
);
1111 wxFD_ZERO(&writefds
);
1112 wxFD_ZERO(&exceptfds
);
1113 wxFD_SET(m_fd
, &readfds
);
1114 if (flags
& wxSOCKET_OUTPUT_FLAG
|| flags
& wxSOCKET_CONNECTION_FLAG
)
1115 wxFD_SET(m_fd
, &writefds
);
1116 wxFD_SET(m_fd
, &exceptfds
);
1118 /* Check 'sticky' CONNECTION flag first */
1119 result
|= wxSOCKET_CONNECTION_FLAG
& m_detected
;
1121 /* If we have already detected a LOST event, then don't try
1122 * to do any further processing.
1124 if ((m_detected
& wxSOCKET_LOST_FLAG
) != 0)
1126 m_establishing
= false;
1127 return (wxSOCKET_LOST_FLAG
& flags
);
1130 /* Try select now */
1131 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
1133 /* What to do here? */
1134 return (result
& flags
);
1137 /* Check for exceptions and errors */
1138 if (wxFD_ISSET(m_fd
, &exceptfds
))
1140 m_establishing
= false;
1141 m_detected
= wxSOCKET_LOST_FLAG
;
1143 /* LOST event: Abort any further processing */
1144 return (wxSOCKET_LOST_FLAG
& flags
);
1147 /* Check for readability */
1148 if (wxFD_ISSET(m_fd
, &readfds
))
1150 result
|= wxSOCKET_INPUT_FLAG
;
1152 if (m_server
&& m_stream
)
1154 /* This is a TCP server socket that detected a connection.
1155 While the INPUT_FLAG is also set, it doesn't matter on
1156 this kind of sockets, as we can only Accept() from them. */
1157 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1161 /* Check for writability */
1162 if (wxFD_ISSET(m_fd
, &writefds
))
1164 if (m_establishing
&& !m_server
)
1167 SOCKOPTLEN_T len
= sizeof(error
);
1168 m_establishing
= false;
1169 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1173 m_detected
= wxSOCKET_LOST_FLAG
;
1175 /* LOST event: Abort any further processing */
1176 return (wxSOCKET_LOST_FLAG
& flags
);
1180 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1185 result
|= wxSOCKET_OUTPUT_FLAG
;
1189 return (result
| m_detected
) & flags
;
1193 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1195 wxCHECK_MSG( m_impl
, false, "can't wait on invalid socket" );
1197 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1198 m_interrupt
= false;
1201 // Use either the provided timeout or the default timeout value associated
1202 // with this socket.
1204 // TODO: allow waiting forever, see #9443
1205 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1206 : seconds
* 1000 + milliseconds
;
1207 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1209 // Get the active event loop which we'll use for the message dispatching
1210 // when running in the main thread unless this was explicitly disabled by
1211 // setting wxSOCKET_BLOCK flag
1212 wxEventLoopBase
*eventLoop
;
1213 if ( !(m_flags
& wxSOCKET_BLOCK
) && wxIsMainThread() )
1215 eventLoop
= wxEventLoop::GetActive();
1217 else // in worker thread
1219 // We never dispatch messages from threads other than the main one.
1223 // Wait until we receive the event we're waiting for or the timeout expires
1224 // (but note that we always execute the loop at least once, even if timeout
1225 // is 0 as this is used for polling)
1226 bool gotEvent
= false;
1227 for ( bool firstTime
= true; !m_interrupt
; firstTime
= false )
1229 long timeLeft
= wxMilliClockToLong(timeEnd
- wxGetLocalTimeMillis());
1238 // This function is only called if wxSOCKET_BLOCK flag was not used and
1239 // so we should dispatch the events if there is an event loop capable
1241 wxSocketEventFlags events
;
1244 // reset them before starting to wait
1247 eventLoop
->DispatchTimeout(timeLeft
);
1249 events
= m_eventsgot
;
1251 else // no event loop or waiting in another thread
1253 // as explained below, we should always check for wxSOCKET_LOST_FLAG
1255 SetTimeValFromMS(tv
, timeLeft
);
1256 events
= m_impl
->Select(flags
| wxSOCKET_LOST_FLAG
, &tv
);
1259 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1260 // it, as continuing to wait for anything else after getting it is
1262 if ( events
& wxSOCKET_LOST_FLAG
)
1264 m_connected
= false;
1265 m_establishing
= false;
1266 if ( flags
& wxSOCKET_LOST_FLAG
)
1271 // otherwise mask out the bits we're not interested in
1274 // Incoming connection (server) or connection established (client)?
1275 if ( events
& wxSOCKET_CONNECTION_FLAG
)
1278 m_establishing
= false;
1283 // Data available or output buffer ready?
1284 if ( (events
& wxSOCKET_INPUT_FLAG
) || (events
& wxSOCKET_OUTPUT_FLAG
) )
1294 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1296 return DoWait(seconds
, milliseconds
,
1297 wxSOCKET_INPUT_FLAG
|
1298 wxSOCKET_OUTPUT_FLAG
|
1299 wxSOCKET_CONNECTION_FLAG
|
1304 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1306 // Check pushback buffer before entering DoWait
1310 // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
1311 // because of the semantics of WaitForRead: a return value of true means
1312 // that a Read call will return immediately, not that there is
1313 // actually data to read.
1314 return DoWait(seconds
, milliseconds
, wxSOCKET_INPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1318 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1320 return DoWait(seconds
, milliseconds
, wxSOCKET_OUTPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1323 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1325 return DoWait(seconds
, milliseconds
, wxSOCKET_LOST_FLAG
);
1328 // --------------------------------------------------------------------------
1330 // --------------------------------------------------------------------------
1333 // Get local or peer address
1336 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
1343 peer
= m_impl
->GetPeer();
1345 // copying a null address would just trigger an assert anyway
1350 addr_man
.SetAddress(peer
);
1351 GAddress_destroy(peer
);
1356 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1363 local
= m_impl
->GetLocal();
1364 addr_man
.SetAddress(local
);
1365 GAddress_destroy(local
);
1371 // Save and restore socket state
1374 void wxSocketBase::SaveState()
1376 wxSocketState
*state
;
1378 state
= new wxSocketState();
1380 state
->m_flags
= m_flags
;
1381 state
->m_notify
= m_notify
;
1382 state
->m_eventmask
= m_eventmask
;
1383 state
->m_clientData
= m_clientData
;
1385 m_states
.Append(state
);
1388 void wxSocketBase::RestoreState()
1390 wxList::compatibility_iterator node
;
1391 wxSocketState
*state
;
1393 node
= m_states
.GetLast();
1397 state
= (wxSocketState
*)node
->GetData();
1399 m_flags
= state
->m_flags
;
1400 m_notify
= state
->m_notify
;
1401 m_eventmask
= state
->m_eventmask
;
1402 m_clientData
= state
->m_clientData
;
1404 m_states
.Erase(node
);
1409 // Timeout and flags
1412 void wxSocketBase::SetTimeout(long seconds
)
1414 m_timeout
= seconds
;
1417 m_impl
->SetTimeout(m_timeout
* 1000);
1420 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1422 // Do some sanity checking on the flags used: not all values can be used
1424 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1425 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1426 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1427 "wxSOCKET_NOWAIT doesn't make sense" );
1433 // --------------------------------------------------------------------------
1435 // --------------------------------------------------------------------------
1437 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1439 wxSocketEventFlags flag
= 0;
1440 switch ( notification
)
1442 case wxSOCKET_INPUT
:
1443 flag
= wxSOCKET_INPUT_FLAG
;
1446 case wxSOCKET_OUTPUT
:
1447 flag
= wxSOCKET_OUTPUT_FLAG
;
1450 case wxSOCKET_CONNECTION
:
1451 flag
= wxSOCKET_CONNECTION_FLAG
;
1455 flag
= wxSOCKET_LOST_FLAG
;
1459 wxFAIL_MSG( "unknown wxSocket notification" );
1462 // if we lost the connection the socket is now closed
1463 if ( notification
== wxSOCKET_LOST
)
1466 // remember the events which were generated for this socket, we're going to
1467 // use this in DoWait()
1468 m_eventsgot
|= flag
;
1470 // send the wx event if enabled and we're interested in it
1471 if ( m_notify
&& (m_eventmask
& flag
) && m_handler
)
1473 // If we are in the middle of a R/W operation, do not propagate events
1474 // to users. Also, filter 'late' events which are no longer valid.
1475 if ( notification
== wxSOCKET_INPUT
)
1477 if ( m_reading
|| !m_impl
->Select(wxSOCKET_INPUT_FLAG
) )
1480 else if ( notification
== wxSOCKET_OUTPUT
)
1482 if ( m_writing
|| !m_impl
->Select(wxSOCKET_OUTPUT_FLAG
) )
1486 wxSocketEvent
event(m_id
);
1487 event
.m_event
= notification
;
1488 event
.m_clientData
= m_clientData
;
1489 event
.SetEventObject(this);
1491 m_handler
->AddPendingEvent(event
);
1495 void wxSocketBase::Notify(bool notify
)
1500 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1502 m_eventmask
= flags
;
1505 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1507 m_handler
= &handler
;
1511 // --------------------------------------------------------------------------
1513 // --------------------------------------------------------------------------
1515 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1519 if (m_unread
== NULL
)
1520 m_unread
= malloc(size
);
1525 tmp
= malloc(m_unrd_size
+ size
);
1526 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1532 m_unrd_size
+= size
;
1534 memcpy(m_unread
, buffer
, size
);
1537 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1539 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1544 if (size
> (m_unrd_size
-m_unrd_cur
))
1545 size
= m_unrd_size
-m_unrd_cur
;
1547 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1552 if (m_unrd_size
== m_unrd_cur
)
1565 // ==========================================================================
1567 // ==========================================================================
1569 // --------------------------------------------------------------------------
1571 // --------------------------------------------------------------------------
1573 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1574 wxSocketFlags flags
)
1575 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1577 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1579 m_impl
= wxSocketImpl::Create(*this);
1583 wxLogTrace( wxTRACE_Socket
, _T("*** Failed to create m_impl") );
1587 // Setup the socket as server
1588 m_impl
->SetLocal(addr_man
.GetAddress());
1590 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1591 m_impl
->SetReusable();
1593 if (GetFlags() & wxSOCKET_BROADCAST
) {
1594 m_impl
->SetBroadcast();
1596 if (GetFlags() & wxSOCKET_NOBIND
) {
1597 m_impl
->DontDoBind();
1600 if (m_impl
->CreateServer() != wxSOCKET_NOERROR
)
1605 wxLogTrace( wxTRACE_Socket
, _T("*** CreateServer() failed") );
1609 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_impl
->m_fd
);
1612 // --------------------------------------------------------------------------
1614 // --------------------------------------------------------------------------
1616 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1618 if ( !m_impl
|| (m_impl
->m_fd
== INVALID_SOCKET
) || !m_impl
->IsServer() )
1620 wxFAIL_MSG( "can only be called for a valid server socket" );
1622 SetError(wxSOCKET_INVSOCK
);
1629 // wait until we get a connection
1630 if ( !m_impl
->SelectWithTimeout(wxSOCKET_INPUT_FLAG
) )
1632 SetError(wxSOCKET_TIMEDOUT
);
1638 sock
.m_impl
= m_impl
->Accept(sock
);
1642 SetError(m_impl
->GetLastError());
1647 sock
.m_type
= wxSOCKET_BASE
;
1648 sock
.m_connected
= true;
1653 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1655 wxSocketBase
* sock
= new wxSocketBase();
1657 sock
->SetFlags(m_flags
);
1659 if (!AcceptWith(*sock
, wait
))
1668 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1670 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
);
1673 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1675 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1677 SOCKOPTLEN_T lenreal
= *optlen
;
1678 if ( getsockopt(m_impl
->m_fd
, level
, optname
,
1679 static_cast<char *>(optval
), &lenreal
) != 0 )
1688 wxSocketBase::SetOption(int level
, int optname
, const void *optval
, int optlen
)
1690 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1692 return setsockopt(m_impl
->m_fd
, level
, optname
,
1693 static_cast<const char *>(optval
), optlen
) == 0;
1696 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1698 GAddress
* la
= local
.GetAddress();
1700 // If the address is valid, save it for use when we call Connect
1701 if (la
&& la
->m_addr
)
1703 m_localAddress
= local
;
1711 // ==========================================================================
1713 // ==========================================================================
1715 // --------------------------------------------------------------------------
1717 // --------------------------------------------------------------------------
1719 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1720 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1722 m_initialRecvBufferSize
=
1723 m_initialSendBufferSize
= -1;
1726 wxSocketClient::~wxSocketClient()
1730 // --------------------------------------------------------------------------
1732 // --------------------------------------------------------------------------
1734 bool wxSocketClient::DoConnect(const wxSockAddress
& remote
,
1735 const wxSockAddress
* local
,
1740 // Shutdown and destroy the old socket
1745 m_connected
= false;
1746 m_establishing
= false;
1748 // Create and set up the new one
1749 m_impl
= wxSocketImpl::Create(*this);
1753 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1754 if (GetFlags() & wxSOCKET_REUSEADDR
)
1755 m_impl
->SetReusable();
1756 if (GetFlags() & wxSOCKET_BROADCAST
)
1757 m_impl
->SetBroadcast();
1758 if (GetFlags() & wxSOCKET_NOBIND
)
1759 m_impl
->DontDoBind();
1761 // Bind to the local IP address and port, when provided or if one had been
1763 if ( !local
&& m_localAddress
.GetAddress() )
1764 local
= &m_localAddress
;
1767 m_impl
->SetLocal(local
->GetAddress());
1769 m_impl
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1771 m_impl
->SetPeer(remote
.GetAddress());
1773 // Finally do create the socket and connect to the peer
1774 const wxSocketError err
= m_impl
->CreateClient(wait
);
1776 if ( err
!= wxSOCKET_NOERROR
)
1778 if ( err
== wxSOCKET_WOULDBLOCK
)
1780 wxASSERT_MSG( !wait
, "shouldn't get this for blocking connect" );
1782 m_establishing
= true;
1792 bool wxSocketClient::Connect(const wxSockAddress
& remote
, bool wait
)
1794 return DoConnect(remote
, NULL
, wait
);
1797 bool wxSocketClient::Connect(const wxSockAddress
& remote
,
1798 const wxSockAddress
& local
,
1801 return DoConnect(remote
, &local
, wait
);
1804 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1808 // this happens if the initial attempt to connect succeeded without
1813 wxCHECK_MSG( m_establishing
&& m_impl
, false,
1814 "No connection establishment attempt in progress" );
1816 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1817 // true if the connection establishment process is finished, whether it is
1818 // over because we successfully connected or because we were not able to
1820 return DoWait(seconds
, milliseconds
,
1821 wxSOCKET_CONNECTION_FLAG
| wxSOCKET_LOST_FLAG
);
1824 // ==========================================================================
1826 // ==========================================================================
1828 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1829 wxSocketFlags flags
)
1830 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1832 // Create the socket
1833 m_impl
= wxSocketImpl::Create(*this);
1838 // Setup the socket as non connection oriented
1839 m_impl
->SetLocal(addr
.GetAddress());
1840 if (flags
& wxSOCKET_REUSEADDR
)
1842 m_impl
->SetReusable();
1844 if (GetFlags() & wxSOCKET_BROADCAST
)
1846 m_impl
->SetBroadcast();
1848 if (GetFlags() & wxSOCKET_NOBIND
)
1850 m_impl
->DontDoBind();
1853 if ( m_impl
->CreateUDP() != wxSOCKET_NOERROR
)
1860 // Initialize all stuff
1861 m_connected
= false;
1862 m_establishing
= false;
1865 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1874 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1878 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1880 m_impl
->SetPeer(addr
.GetAddress());
1885 // ==========================================================================
1887 // ==========================================================================
1889 class wxSocketModule
: public wxModule
1892 virtual bool OnInit()
1894 // wxSocketBase will call Initialize() itself only if sockets are
1895 // really used, don't do it from here
1899 virtual void OnExit()
1901 if ( wxSocketBase::IsInitialized() )
1902 wxSocketBase::Shutdown();
1906 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1909 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1911 #endif // wxUSE_SOCKETS