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
;
604 m_beingDeleted
= false;
619 if ( !IsInitialized() )
621 // this Initialize() will be undone by wxSocketModule::OnExit(), all
622 // the other calls to it should be matched by a call to Shutdown()
627 wxSocketBase::wxSocketBase()
632 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
641 wxSocketBase::~wxSocketBase()
643 // Just in case the app called Destroy() *and* then deleted the socket
644 // immediately: don't leave dangling pointers.
645 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
647 traits
->RemoveFromPendingDelete(this);
649 // Shutdown and close the socket
653 // Destroy the implementation object
656 // Free the pushback buffer
661 bool wxSocketBase::Destroy()
663 // Delayed destruction: the socket will be deleted during the next idle
664 // loop iteration. This ensures that all pending events have been
666 m_beingDeleted
= true;
668 // Shutdown and close the socket
671 // Suppress events from now on
674 // schedule this object for deletion
675 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
678 // let the traits object decide what to do with us
679 traits
->ScheduleForDestroy(this);
681 else // no app or no traits
683 // in wxBase we might have no app object at all, don't leak memory
690 // ----------------------------------------------------------------------------
692 // ----------------------------------------------------------------------------
694 wxSocketError
wxSocketBase::LastError() const
696 return m_impl
->GetError();
699 // --------------------------------------------------------------------------
701 // --------------------------------------------------------------------------
703 // The following IO operations update m_error and m_lcount:
704 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
705 bool wxSocketBase::Close()
707 // Interrupt pending waits
714 m_establishing
= false;
718 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
723 m_lcount
= DoRead(buffer
, nbytes
);
725 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
726 if (m_flags
& wxSOCKET_WAITALL
)
727 m_error
= (m_lcount
!= nbytes
);
729 m_error
= (m_lcount
== 0);
731 // Allow read events from now on
737 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
739 // We use pointer arithmetic here which doesn't work with void pointers.
740 char *buffer
= static_cast<char *>(buffer_
);
742 // Try the push back buffer first, even before checking whether the socket
743 // is valid to allow reading previously pushed back data from an already
745 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
749 // If it's indeed closed or if read everything, there is nothing more to do.
750 if ( !m_impl
|| !nbytes
)
753 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
756 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
757 // polling the socket and don't block at all.
758 if ( m_flags
& wxSOCKET_NOWAIT
)
760 int ret
= m_impl
->Read(buffer
, nbytes
);
766 else // blocking socket
770 // Wait until socket becomes ready for reading
771 if ( !WaitForRead() )
774 const int ret
= m_impl
->Read(buffer
, nbytes
);
777 // for connection-oriented (e.g. TCP) sockets we can only read
778 // 0 bytes if the other end has been closed, and for
779 // connectionless ones (UDP) this flag doesn't make sense
780 // anyhow so we can set it to true too without doing any harm
787 // this will be always interpreted as error by Read()
793 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
794 // something and we don't need to wait for all nbytes bytes to be
796 if ( !(m_flags
& wxSOCKET_WAITALL
) )
799 // Otherwise continue reading until we do read everything.
811 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
813 wxUint32 len
, len2
, sig
, total
;
818 unsigned char sig
[4];
819 unsigned char len
[4];
828 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
830 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
833 sig
= (wxUint32
)msg
.sig
[0];
834 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
835 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
836 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
838 if (sig
!= 0xfeeddead)
840 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
844 len
= (wxUint32
)msg
.len
[0];
845 len
|= (wxUint32
)(msg
.len
[1] << 8);
846 len
|= (wxUint32
)(msg
.len
[2] << 16);
847 len
|= (wxUint32
)(msg
.len
[3] << 24);
857 // Don't attempt to read if the msg was zero bytes long.
860 total
= DoRead(buffer
, len
);
868 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
871 // NOTE: discarded bytes don't add to m_lcount.
874 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
875 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
876 len2
-= (wxUint32
)discard_len
;
878 while ((discard_len
> 0) && len2
);
880 delete [] discard_buffer
;
885 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
888 sig
= (wxUint32
)msg
.sig
[0];
889 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
890 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
891 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
893 if (sig
!= 0xdeadfeed)
895 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
911 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
916 m_lcount
= DoRead(buffer
, nbytes
);
917 Pushback(buffer
, m_lcount
);
919 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
920 if (m_flags
& wxSOCKET_WAITALL
)
921 m_error
= (m_lcount
!= nbytes
);
923 m_error
= (m_lcount
== 0);
925 // Allow read events again
931 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
936 m_lcount
= DoWrite(buffer
, nbytes
);
938 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
939 if (m_flags
& wxSOCKET_WAITALL
)
940 m_error
= (m_lcount
!= nbytes
);
942 m_error
= (m_lcount
== 0);
944 // Allow write events again
950 // This function is a mirror image of DoRead() except that it doesn't use the
951 // push back buffer, please see comments there
952 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
954 const char *buffer
= static_cast<const char *>(buffer_
);
956 // Return if there is nothing to read or the socket is (already?) closed.
957 if ( !m_impl
|| !nbytes
)
960 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
963 if ( m_flags
& wxSOCKET_NOWAIT
)
965 const int ret
= m_impl
->Write(buffer
, nbytes
);
969 else // blocking socket
973 if ( !WaitForWrite() )
976 const int ret
= m_impl
->Write(buffer
, nbytes
);
987 if ( !(m_flags
& wxSOCKET_WAITALL
) )
1001 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
1007 unsigned char sig
[4];
1008 unsigned char len
[4];
1011 // Mask write events
1016 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
1018 msg
.sig
[0] = (unsigned char) 0xad;
1019 msg
.sig
[1] = (unsigned char) 0xde;
1020 msg
.sig
[2] = (unsigned char) 0xed;
1021 msg
.sig
[3] = (unsigned char) 0xfe;
1023 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
1024 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
1025 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
1026 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
1028 if (DoWrite(&msg
, sizeof(msg
)) < sizeof(msg
))
1031 total
= DoWrite(buffer
, nbytes
);
1036 msg
.sig
[0] = (unsigned char) 0xed;
1037 msg
.sig
[1] = (unsigned char) 0xfe;
1038 msg
.sig
[2] = (unsigned char) 0xad;
1039 msg
.sig
[3] = (unsigned char) 0xde;
1043 msg
.len
[3] = (char) 0;
1045 if ((DoWrite(&msg
, sizeof(msg
))) < sizeof(msg
))
1048 // everything was OK
1059 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
1062 Pushback(buffer
, nbytes
);
1070 wxSocketBase
& wxSocketBase::Discard()
1072 char *buffer
= new char[MAX_DISCARD_SIZE
];
1079 SetFlags(wxSOCKET_NOWAIT
);
1083 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
1086 while (ret
== MAX_DISCARD_SIZE
);
1092 // Allow read events again
1098 // --------------------------------------------------------------------------
1100 // --------------------------------------------------------------------------
1103 This function will check for the events specified in the flags parameter,
1104 and it will return a mask indicating which operations can be performed.
1106 wxSocketEventFlags
wxSocketImpl::Select(wxSocketEventFlags flags
,
1107 const timeval
*timeout
)
1109 wxSocketEventFlags result
= 0;
1111 if (m_fd
== INVALID_SOCKET
)
1112 return (wxSOCKET_LOST_FLAG
& flags
);
1118 tv
.tv_sec
= tv
.tv_usec
= 0;
1123 wxFD_ZERO(&readfds
);
1124 wxFD_ZERO(&writefds
);
1125 wxFD_ZERO(&exceptfds
);
1126 wxFD_SET(m_fd
, &readfds
);
1127 if (flags
& wxSOCKET_OUTPUT_FLAG
|| flags
& wxSOCKET_CONNECTION_FLAG
)
1128 wxFD_SET(m_fd
, &writefds
);
1129 wxFD_SET(m_fd
, &exceptfds
);
1131 /* Check 'sticky' CONNECTION flag first */
1132 result
|= wxSOCKET_CONNECTION_FLAG
& m_detected
;
1134 /* If we have already detected a LOST event, then don't try
1135 * to do any further processing.
1137 if ((m_detected
& wxSOCKET_LOST_FLAG
) != 0)
1139 m_establishing
= false;
1140 return (wxSOCKET_LOST_FLAG
& flags
);
1143 /* Try select now */
1144 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
1146 /* What to do here? */
1147 return (result
& flags
);
1150 /* Check for exceptions and errors */
1151 if (wxFD_ISSET(m_fd
, &exceptfds
))
1153 m_establishing
= false;
1154 m_detected
= wxSOCKET_LOST_FLAG
;
1156 /* LOST event: Abort any further processing */
1157 return (wxSOCKET_LOST_FLAG
& flags
);
1160 /* Check for readability */
1161 if (wxFD_ISSET(m_fd
, &readfds
))
1163 result
|= wxSOCKET_INPUT_FLAG
;
1165 if (m_server
&& m_stream
)
1167 /* This is a TCP server socket that detected a connection.
1168 While the INPUT_FLAG is also set, it doesn't matter on
1169 this kind of sockets, as we can only Accept() from them. */
1170 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1174 /* Check for writability */
1175 if (wxFD_ISSET(m_fd
, &writefds
))
1177 if (m_establishing
&& !m_server
)
1180 SOCKOPTLEN_T len
= sizeof(error
);
1181 m_establishing
= false;
1182 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1186 m_detected
= wxSOCKET_LOST_FLAG
;
1188 /* LOST event: Abort any further processing */
1189 return (wxSOCKET_LOST_FLAG
& flags
);
1193 m_detected
|= wxSOCKET_CONNECTION_FLAG
;
1198 result
|= wxSOCKET_OUTPUT_FLAG
;
1202 return (result
| m_detected
) & flags
;
1206 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1208 wxCHECK_MSG( m_impl
, false, "can't wait on invalid socket" );
1210 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1211 m_interrupt
= false;
1214 // Use either the provided timeout or the default timeout value associated
1215 // with this socket.
1217 // TODO: allow waiting forever, see #9443
1218 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1219 : seconds
* 1000 + milliseconds
;
1220 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1222 // Get the active event loop which we'll use for the message dispatching
1223 // when running in the main thread unless this was explicitly disabled by
1224 // setting wxSOCKET_BLOCK flag
1225 wxEventLoopBase
*eventLoop
;
1226 if ( !(m_flags
& wxSOCKET_BLOCK
) && wxIsMainThread() )
1228 eventLoop
= wxEventLoop::GetActive();
1230 else // in worker thread
1232 // We never dispatch messages from threads other than the main one.
1236 // Wait until we receive the event we're waiting for or the timeout expires
1237 // (but note that we always execute the loop at least once, even if timeout
1238 // is 0 as this is used for polling)
1239 bool gotEvent
= false;
1240 for ( bool firstTime
= true; !m_interrupt
; firstTime
= false )
1242 long timeLeft
= wxMilliClockToLong(timeEnd
- wxGetLocalTimeMillis());
1251 // This function is only called if wxSOCKET_BLOCK flag was not used and
1252 // so we should dispatch the events if there is an event loop capable
1254 wxSocketEventFlags events
;
1257 // reset them before starting to wait
1260 eventLoop
->DispatchTimeout(timeLeft
);
1262 events
= m_eventsgot
;
1264 else // no event loop or waiting in another thread
1266 // as explained below, we should always check for wxSOCKET_LOST_FLAG
1268 SetTimeValFromMS(tv
, timeLeft
);
1269 events
= m_impl
->Select(flags
| wxSOCKET_LOST_FLAG
, &tv
);
1272 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1273 // it, as continuing to wait for anything else after getting it is
1275 if ( events
& wxSOCKET_LOST_FLAG
)
1277 m_connected
= false;
1278 m_establishing
= false;
1279 if ( flags
& wxSOCKET_LOST_FLAG
)
1284 // otherwise mask out the bits we're not interested in
1287 // Incoming connection (server) or connection established (client)?
1288 if ( events
& wxSOCKET_CONNECTION_FLAG
)
1291 m_establishing
= false;
1296 // Data available or output buffer ready?
1297 if ( (events
& wxSOCKET_INPUT_FLAG
) || (events
& wxSOCKET_OUTPUT_FLAG
) )
1307 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1309 return DoWait(seconds
, milliseconds
,
1310 wxSOCKET_INPUT_FLAG
|
1311 wxSOCKET_OUTPUT_FLAG
|
1312 wxSOCKET_CONNECTION_FLAG
|
1317 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1319 // Check pushback buffer before entering DoWait
1323 // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
1324 // because of the semantics of WaitForRead: a return value of true means
1325 // that a Read call will return immediately, not that there is
1326 // actually data to read.
1327 return DoWait(seconds
, milliseconds
, wxSOCKET_INPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1331 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1333 return DoWait(seconds
, milliseconds
, wxSOCKET_OUTPUT_FLAG
| wxSOCKET_LOST_FLAG
);
1336 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1338 return DoWait(seconds
, milliseconds
, wxSOCKET_LOST_FLAG
);
1341 // --------------------------------------------------------------------------
1343 // --------------------------------------------------------------------------
1346 // Get local or peer address
1349 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
1356 peer
= m_impl
->GetPeer();
1358 // copying a null address would just trigger an assert anyway
1363 addr_man
.SetAddress(peer
);
1364 GAddress_destroy(peer
);
1369 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1376 local
= m_impl
->GetLocal();
1377 addr_man
.SetAddress(local
);
1378 GAddress_destroy(local
);
1384 // Save and restore socket state
1387 void wxSocketBase::SaveState()
1389 wxSocketState
*state
;
1391 state
= new wxSocketState();
1393 state
->m_flags
= m_flags
;
1394 state
->m_notify
= m_notify
;
1395 state
->m_eventmask
= m_eventmask
;
1396 state
->m_clientData
= m_clientData
;
1398 m_states
.Append(state
);
1401 void wxSocketBase::RestoreState()
1403 wxList::compatibility_iterator node
;
1404 wxSocketState
*state
;
1406 node
= m_states
.GetLast();
1410 state
= (wxSocketState
*)node
->GetData();
1412 m_flags
= state
->m_flags
;
1413 m_notify
= state
->m_notify
;
1414 m_eventmask
= state
->m_eventmask
;
1415 m_clientData
= state
->m_clientData
;
1417 m_states
.Erase(node
);
1422 // Timeout and flags
1425 void wxSocketBase::SetTimeout(long seconds
)
1427 m_timeout
= seconds
;
1430 m_impl
->SetTimeout(m_timeout
* 1000);
1433 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1435 // Do some sanity checking on the flags used: not all values can be used
1437 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1438 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1439 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1440 "wxSOCKET_NOWAIT doesn't make sense" );
1446 // --------------------------------------------------------------------------
1448 // --------------------------------------------------------------------------
1450 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1452 wxSocketEventFlags flag
= 0;
1453 switch ( notification
)
1455 case wxSOCKET_INPUT
:
1456 flag
= wxSOCKET_INPUT_FLAG
;
1459 case wxSOCKET_OUTPUT
:
1460 flag
= wxSOCKET_OUTPUT_FLAG
;
1463 case wxSOCKET_CONNECTION
:
1464 flag
= wxSOCKET_CONNECTION_FLAG
;
1468 flag
= wxSOCKET_LOST_FLAG
;
1472 wxFAIL_MSG( "unknown wxSocket notification" );
1475 // if we lost the connection the socket is now closed
1476 if ( notification
== wxSOCKET_LOST
)
1479 // remember the events which were generated for this socket, we're going to
1480 // use this in DoWait()
1481 m_eventsgot
|= flag
;
1483 // send the wx event if enabled and we're interested in it
1484 if ( m_notify
&& (m_eventmask
& flag
) && m_handler
)
1486 // If we are in the middle of a R/W operation, do not propagate events
1487 // to users. Also, filter 'late' events which are no longer valid.
1488 if ( notification
== wxSOCKET_INPUT
)
1490 if ( m_reading
|| !m_impl
->Select(wxSOCKET_INPUT_FLAG
) )
1493 else if ( notification
== wxSOCKET_OUTPUT
)
1495 if ( m_writing
|| !m_impl
->Select(wxSOCKET_OUTPUT_FLAG
) )
1499 wxSocketEvent
event(m_id
);
1500 event
.m_event
= notification
;
1501 event
.m_clientData
= m_clientData
;
1502 event
.SetEventObject(this);
1504 m_handler
->AddPendingEvent(event
);
1508 void wxSocketBase::Notify(bool notify
)
1513 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1515 m_eventmask
= flags
;
1518 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1520 m_handler
= &handler
;
1524 // --------------------------------------------------------------------------
1526 // --------------------------------------------------------------------------
1528 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1532 if (m_unread
== NULL
)
1533 m_unread
= malloc(size
);
1538 tmp
= malloc(m_unrd_size
+ size
);
1539 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1545 m_unrd_size
+= size
;
1547 memcpy(m_unread
, buffer
, size
);
1550 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1552 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1557 if (size
> (m_unrd_size
-m_unrd_cur
))
1558 size
= m_unrd_size
-m_unrd_cur
;
1560 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1565 if (m_unrd_size
== m_unrd_cur
)
1578 // ==========================================================================
1580 // ==========================================================================
1582 // --------------------------------------------------------------------------
1584 // --------------------------------------------------------------------------
1586 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1587 wxSocketFlags flags
)
1588 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1590 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1592 m_impl
= wxSocketImpl::Create(*this);
1596 wxLogTrace( wxTRACE_Socket
, _T("*** Failed to create m_impl") );
1600 // Setup the socket as server
1601 m_impl
->SetLocal(addr_man
.GetAddress());
1603 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1604 m_impl
->SetReusable();
1606 if (GetFlags() & wxSOCKET_BROADCAST
) {
1607 m_impl
->SetBroadcast();
1609 if (GetFlags() & wxSOCKET_NOBIND
) {
1610 m_impl
->DontDoBind();
1613 if (m_impl
->CreateServer() != wxSOCKET_NOERROR
)
1618 wxLogTrace( wxTRACE_Socket
, _T("*** CreateServer() failed") );
1622 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_impl
->m_fd
);
1625 // --------------------------------------------------------------------------
1627 // --------------------------------------------------------------------------
1629 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1631 if ( !m_impl
|| (m_impl
->m_fd
== INVALID_SOCKET
) || !m_impl
->IsServer() )
1633 wxFAIL_MSG( "can only be called for a valid server socket" );
1635 m_error
= wxSOCKET_INVSOCK
;
1642 // wait until we get a connection
1643 if ( !m_impl
->SelectWithTimeout(wxSOCKET_INPUT_FLAG
) )
1645 m_error
= wxSOCKET_TIMEDOUT
;
1651 sock
.m_impl
= m_impl
->Accept(sock
);
1655 m_error
= m_impl
->GetLastError();
1660 sock
.m_type
= wxSOCKET_BASE
;
1661 sock
.m_connected
= true;
1666 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1668 wxSocketBase
* sock
= new wxSocketBase();
1670 sock
->SetFlags(m_flags
);
1672 if (!AcceptWith(*sock
, wait
))
1681 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1683 return DoWait(seconds
, milliseconds
, wxSOCKET_CONNECTION_FLAG
);
1686 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1688 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1690 SOCKOPTLEN_T lenreal
= *optlen
;
1691 if ( getsockopt(m_impl
->m_fd
, level
, optname
,
1692 static_cast<char *>(optval
), &lenreal
) != 0 )
1701 wxSocketBase::SetOption(int level
, int optname
, const void *optval
, int optlen
)
1703 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1705 return setsockopt(m_impl
->m_fd
, level
, optname
,
1706 static_cast<const char *>(optval
), optlen
) == 0;
1709 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1711 GAddress
* la
= local
.GetAddress();
1713 // If the address is valid, save it for use when we call Connect
1714 if (la
&& la
->m_addr
)
1716 m_localAddress
= local
;
1724 // ==========================================================================
1726 // ==========================================================================
1728 // --------------------------------------------------------------------------
1730 // --------------------------------------------------------------------------
1732 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1733 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1735 m_initialRecvBufferSize
=
1736 m_initialSendBufferSize
= -1;
1739 wxSocketClient::~wxSocketClient()
1743 // --------------------------------------------------------------------------
1745 // --------------------------------------------------------------------------
1747 bool wxSocketClient::DoConnect(const wxSockAddress
& remote
,
1748 const wxSockAddress
* local
,
1753 // Shutdown and destroy the old socket
1758 m_connected
= false;
1759 m_establishing
= false;
1761 // Create and set up the new one
1762 m_impl
= wxSocketImpl::Create(*this);
1766 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1767 if (GetFlags() & wxSOCKET_REUSEADDR
)
1768 m_impl
->SetReusable();
1769 if (GetFlags() & wxSOCKET_BROADCAST
)
1770 m_impl
->SetBroadcast();
1771 if (GetFlags() & wxSOCKET_NOBIND
)
1772 m_impl
->DontDoBind();
1774 // Bind to the local IP address and port, when provided or if one had been
1776 if ( !local
&& m_localAddress
.GetAddress() )
1777 local
= &m_localAddress
;
1780 m_impl
->SetLocal(local
->GetAddress());
1782 m_impl
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1784 m_impl
->SetPeer(remote
.GetAddress());
1786 // Finally do create the socket and connect to the peer
1787 const wxSocketError err
= m_impl
->CreateClient(wait
);
1789 if ( err
!= wxSOCKET_NOERROR
)
1791 if ( err
== wxSOCKET_WOULDBLOCK
)
1793 wxASSERT_MSG( !wait
, "shouldn't get this for blocking connect" );
1795 m_establishing
= true;
1805 bool wxSocketClient::Connect(const wxSockAddress
& remote
, bool wait
)
1807 return DoConnect(remote
, NULL
, wait
);
1810 bool wxSocketClient::Connect(const wxSockAddress
& remote
,
1811 const wxSockAddress
& local
,
1814 return DoConnect(remote
, &local
, wait
);
1817 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1821 // this happens if the initial attempt to connect succeeded without
1826 wxCHECK_MSG( m_establishing
&& m_impl
, false,
1827 "No connection establishment attempt in progress" );
1829 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1830 // true if the connection establishment process is finished, whether it is
1831 // over because we successfully connected or because we were not able to
1833 return DoWait(seconds
, milliseconds
,
1834 wxSOCKET_CONNECTION_FLAG
| wxSOCKET_LOST_FLAG
);
1837 // ==========================================================================
1839 // ==========================================================================
1841 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1842 wxSocketFlags flags
)
1843 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1845 // Create the socket
1846 m_impl
= wxSocketImpl::Create(*this);
1851 // Setup the socket as non connection oriented
1852 m_impl
->SetLocal(addr
.GetAddress());
1853 if (flags
& wxSOCKET_REUSEADDR
)
1855 m_impl
->SetReusable();
1857 if (GetFlags() & wxSOCKET_BROADCAST
)
1859 m_impl
->SetBroadcast();
1861 if (GetFlags() & wxSOCKET_NOBIND
)
1863 m_impl
->DontDoBind();
1866 if ( m_impl
->CreateUDP() != wxSOCKET_NOERROR
)
1873 // Initialize all stuff
1874 m_connected
= false;
1875 m_establishing
= false;
1878 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1887 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1891 wxASSERT_MSG( m_impl
, _T("Socket not initialised") );
1893 m_impl
->SetPeer(addr
.GetAddress());
1898 // ==========================================================================
1900 // ==========================================================================
1902 class wxSocketModule
: public wxModule
1905 virtual bool OnInit()
1907 // wxSocketBase will call Initialize() itself only if sockets are
1908 // really used, don't do it from here
1912 virtual void OnExit()
1914 if ( wxSocketBase::IsInitialized() )
1915 wxSocketBase::Shutdown();
1919 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1922 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1924 #endif // wxUSE_SOCKETS