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) 2000-1999, Guillermo Rodriguez Garcia
9 // License: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ==========================================================================
14 // ==========================================================================
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 #include "wx/socket.h"
28 #include "wx/object.h"
29 #include "wx/string.h"
36 #include "wx/module.h"
39 #include "wx/apptrait.h"
40 #include "wx/sckaddr.h"
41 #include "wx/stopwatch.h"
42 #include "wx/thread.h"
43 #include "wx/evtloop.h"
45 #include "wx/private/fd.h"
46 #include "wx/private/socket.h"
48 // DLL options compatibility check:
50 WX_CHECK_BUILD_OPTIONS("wxNet")
52 // --------------------------------------------------------------------------
53 // macros and constants
54 // --------------------------------------------------------------------------
57 #define MAX_DISCARD_SIZE (10 * 1024)
59 #define wxTRACE_Socket _T("wxSocket")
61 // --------------------------------------------------------------------------
63 // --------------------------------------------------------------------------
65 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
66 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
67 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
68 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
69 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
71 // --------------------------------------------------------------------------
73 // --------------------------------------------------------------------------
75 class wxSocketState
: public wxObject
78 wxSocketFlags m_flags
;
79 wxSocketEventFlags m_eventmask
;
84 wxSocketState() : wxObject() {}
86 DECLARE_NO_COPY_CLASS(wxSocketState
)
89 // Conditionally make the socket non-blocking for the lifetime of this object.
90 class wxSocketUnblocker
93 wxSocketUnblocker(GSocket
*socket
, bool unblock
= true)
98 m_socket
->SetNonBlocking(true);
104 m_socket
->SetNonBlocking(false);
108 GSocket
* const m_socket
;
111 DECLARE_NO_COPY_CLASS(wxSocketUnblocker
)
114 // ============================================================================
116 // ============================================================================
118 GSocketManager
*GSocketManager::ms_manager
= NULL
;
121 void GSocketManager::Set(GSocketManager
*manager
)
123 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
125 ms_manager
= manager
;
129 void GSocketManager::Init()
131 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
134 Details: Initialize() creates a hidden window as a sink for socket
135 events, such as 'read completed'. wxMSW has only one message loop
136 for the main thread. If Initialize is called in a secondary thread,
137 the socket window will be created for the secondary thread, but
138 since there is no message loop on this thread, it will never
139 receive events and all socket operations will time out.
140 BTW, the main thread must not be stopped using sleep or block
141 on a semaphore (a bad idea in any case) or socket operations
144 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
145 the main thread. Because secondary threads do not have run loops,
146 adding event notifications to the "Current" loop would have no
147 effect at all, events would never fire.
149 wxASSERT_MSG( wxIsMainThread(),
150 "sockets must be initialized from the main thread" );
152 wxAppConsole
* const app
= wxAppConsole::GetInstance();
153 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
155 ms_manager
= app
->GetTraits()->GetSocketManager();
158 // ==========================================================================
160 // ==========================================================================
163 GSocket
*GSocketBase::Create(wxSocketBase
& wxsocket
)
165 GSocket
* const newsocket
= new GSocket(wxsocket
);
166 if ( !GSocketManager::Get()->Init_Socket(newsocket
) )
175 GSocketBase::GSocketBase(wxSocketBase
& wxsocket
)
176 : m_wxsocket(&wxsocket
)
178 m_fd
= INVALID_SOCKET
;
182 m_error
= GSOCK_NOERROR
;
185 m_non_blocking
= false;
187 SetTimeout(wxsocket
.GetTimeout() * 1000);
189 m_establishing
= false;
193 m_initialRecvBufferSize
= -1;
194 m_initialSendBufferSize
= -1;
197 GSocketBase::~GSocketBase()
199 if (m_fd
!= INVALID_SOCKET
)
203 GAddress_destroy(m_local
);
206 GAddress_destroy(m_peer
);
208 // cast is ok as all GSocketBase objects we have in our code are really
210 GSocketManager::Get()->Destroy_Socket(static_cast<GSocket
*>(this));
214 * Disallow further read/write operations on this socket, close
215 * the fd and disable all callbacks.
217 void GSocketBase::Shutdown()
219 if ( m_fd
!= INVALID_SOCKET
)
221 shutdown(m_fd
, 1 /* SD_SEND */);
225 m_detected
= GSOCK_LOST_FLAG
;
228 /* GSocket_SetTimeout:
229 * Sets the timeout for blocking calls. Time is expressed in
232 void GSocketBase::SetTimeout(unsigned long millis
)
234 m_timeout
.tv_sec
= (millis
/ 1000);
235 m_timeout
.tv_usec
= (millis
% 1000) * 1000;
238 void GSocketBase::NotifyOnStateChange(GSocketEvent event
)
240 // GSocketEvent and wxSocketNotify enums have the same elements with the
242 m_wxsocket
->OnRequest(static_cast<wxSocketNotify
>(event
));
245 /* Address handling */
251 * Set or get the local or peer address for this socket. The 'set'
252 * functions return GSOCK_NOERROR on success, an error code otherwise.
253 * The 'get' functions return a pointer to a GAddress object on success,
254 * or NULL otherwise, in which case they set the error code of the
255 * corresponding GSocket.
258 * GSOCK_INVSOCK - the socket is not valid.
259 * GSOCK_INVADDR - the address is not valid.
261 GSocketError
GSocketBase::SetLocal(GAddress
*address
)
263 /* the socket must be initialized, or it must be a server */
264 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
266 m_error
= GSOCK_INVSOCK
;
267 return GSOCK_INVSOCK
;
271 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
273 m_error
= GSOCK_INVADDR
;
274 return GSOCK_INVADDR
;
278 GAddress_destroy(m_local
);
280 m_local
= GAddress_copy(address
);
282 return GSOCK_NOERROR
;
285 GSocketError
GSocketBase::SetPeer(GAddress
*address
)
288 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
290 m_error
= GSOCK_INVADDR
;
291 return GSOCK_INVADDR
;
295 GAddress_destroy(m_peer
);
297 m_peer
= GAddress_copy(address
);
299 return GSOCK_NOERROR
;
302 GAddress
*GSocketBase::GetLocal()
306 WX_SOCKLEN_T size
= sizeof(addr
);
309 /* try to get it from the m_local var first */
311 return GAddress_copy(m_local
);
313 /* else, if the socket is initialized, try getsockname */
314 if (m_fd
== INVALID_SOCKET
)
316 m_error
= GSOCK_INVSOCK
;
320 if (getsockname(m_fd
, (sockaddr
*)&addr
, &size
) == SOCKET_ERROR
)
322 m_error
= GSOCK_IOERR
;
326 /* got a valid address from getsockname, create a GAddress object */
327 if ((address
= GAddress_new()) == NULL
)
329 m_error
= GSOCK_MEMERR
;
333 if ((err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
)) != GSOCK_NOERROR
)
335 GAddress_destroy(address
);
343 GAddress
*GSocketBase::GetPeer()
345 /* try to get it from the m_peer var */
347 return GAddress_copy(m_peer
);
352 // ==========================================================================
354 // ==========================================================================
356 // --------------------------------------------------------------------------
357 // Initialization and shutdown
358 // --------------------------------------------------------------------------
360 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
361 // to m_countInit with a crit section
362 size_t wxSocketBase::m_countInit
= 0;
364 bool wxSocketBase::IsInitialized()
366 return m_countInit
> 0;
369 bool wxSocketBase::Initialize()
371 if ( !m_countInit
++ )
373 if ( !GSocket_Init() )
384 void wxSocketBase::Shutdown()
386 // we should be initialized
387 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
388 if ( --m_countInit
== 0 )
394 // --------------------------------------------------------------------------
396 // --------------------------------------------------------------------------
398 void wxSocketBase::Init()
401 m_type
= wxSOCKET_UNINIT
;
413 m_beingDeleted
= false;
427 if ( !IsInitialized() )
429 // this Initialize() will be undone by wxSocketModule::OnExit(), all
430 // the other calls to it should be matched by a call to Shutdown()
435 wxSocketBase::wxSocketBase()
440 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
449 wxSocketBase::~wxSocketBase()
451 // Just in case the app called Destroy() *and* then deleted the socket
452 // immediately: don't leave dangling pointers.
453 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
455 traits
->RemoveFromPendingDelete(this);
457 // Shutdown and close the socket
461 // Destroy the GSocket object
465 // Free the pushback buffer
470 bool wxSocketBase::Destroy()
472 // Delayed destruction: the socket will be deleted during the next idle
473 // loop iteration. This ensures that all pending events have been
475 m_beingDeleted
= true;
477 // Shutdown and close the socket
480 // Supress events from now on
483 // schedule this object for deletion
484 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
487 // let the traits object decide what to do with us
488 traits
->ScheduleForDestroy(this);
490 else // no app or no traits
492 // in wxBase we might have no app object at all, don't leak memory
499 // --------------------------------------------------------------------------
501 // --------------------------------------------------------------------------
503 // The following IO operations update m_error and m_lcount:
504 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
506 // TODO: Should Connect, Accept and AcceptWith update m_error?
508 bool wxSocketBase::Close()
510 // Interrupt pending waits
514 m_socket
->Shutdown();
517 m_establishing
= false;
521 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
526 m_lcount
= DoRead(buffer
, nbytes
);
528 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
529 if (m_flags
& wxSOCKET_WAITALL
)
530 m_error
= (m_lcount
!= nbytes
);
532 m_error
= (m_lcount
== 0);
534 // Allow read events from now on
540 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
542 // We use pointer arithmetic here which doesn't work with void pointers.
543 char *buffer
= static_cast<char *>(buffer_
);
545 // Try the push back buffer first, even before checking whether the socket
546 // is valid to allow reading previously pushed back data from an already
548 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
552 // If it's indeed closed or if read everything, there is nothing more to do.
553 if ( !m_socket
|| !nbytes
)
556 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
559 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
560 // polling the socket and don't block at all.
561 if ( m_flags
& wxSOCKET_NOWAIT
)
563 wxSocketUnblocker
unblock(m_socket
);
564 int ret
= m_socket
->Read(buffer
, nbytes
);
570 else // blocking socket
574 // Wait until socket becomes ready for reading dispatching the GUI
575 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
576 // specified to disable this.
577 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
580 const int ret
= m_socket
->Read(buffer
, nbytes
);
583 // for connection-oriented (e.g. TCP) sockets we can only read
584 // 0 bytes if the other end has been closed, and for
585 // connectionless ones (UDP) this flag doesn't make sense
586 // anyhow so we can set it to true too without doing any harm
593 // this will be always interpreted as error by Read()
599 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
600 // something and we don't need to wait for all nbytes bytes to be
602 if ( !(m_flags
& wxSOCKET_WAITALL
) )
605 // Otherwise continue reading until we do read everything.
617 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
619 wxUint32 len
, len2
, sig
, total
;
624 unsigned char sig
[4];
625 unsigned char len
[4];
634 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
636 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
639 sig
= (wxUint32
)msg
.sig
[0];
640 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
641 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
642 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
644 if (sig
!= 0xfeeddead)
646 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
650 len
= (wxUint32
)msg
.len
[0];
651 len
|= (wxUint32
)(msg
.len
[1] << 8);
652 len
|= (wxUint32
)(msg
.len
[2] << 16);
653 len
|= (wxUint32
)(msg
.len
[3] << 24);
663 // Don't attempt to read if the msg was zero bytes long.
666 total
= DoRead(buffer
, len
);
674 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
677 // NOTE: discarded bytes don't add to m_lcount.
680 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
681 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
682 len2
-= (wxUint32
)discard_len
;
684 while ((discard_len
> 0) && len2
);
686 delete [] discard_buffer
;
691 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
694 sig
= (wxUint32
)msg
.sig
[0];
695 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
696 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
697 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
699 if (sig
!= 0xdeadfeed)
701 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
717 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
722 m_lcount
= DoRead(buffer
, nbytes
);
723 Pushback(buffer
, m_lcount
);
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 again
737 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
742 m_lcount
= DoWrite(buffer
, nbytes
);
744 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
745 if (m_flags
& wxSOCKET_WAITALL
)
746 m_error
= (m_lcount
!= nbytes
);
748 m_error
= (m_lcount
== 0);
750 // Allow write events again
756 // This function is a mirror image of DoRead() except that it doesn't use the
757 // push back buffer, please see comments there
758 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
760 const char *buffer
= static_cast<const char *>(buffer_
);
762 // Return if there is nothing to read or the socket is (already?) closed.
763 if ( !m_socket
|| !nbytes
)
766 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
769 if ( m_flags
& wxSOCKET_NOWAIT
)
771 wxSocketUnblocker
unblock(m_socket
);
772 const int ret
= m_socket
->Write(buffer
, nbytes
);
776 else // blocking socket
780 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
783 const int ret
= m_socket
->Write(buffer
, nbytes
);
794 if ( !(m_flags
& wxSOCKET_WAITALL
) )
808 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
814 unsigned char sig
[4];
815 unsigned char len
[4];
823 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
825 msg
.sig
[0] = (unsigned char) 0xad;
826 msg
.sig
[1] = (unsigned char) 0xde;
827 msg
.sig
[2] = (unsigned char) 0xed;
828 msg
.sig
[3] = (unsigned char) 0xfe;
830 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
831 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
832 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
833 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
835 if (DoWrite(&msg
, sizeof(msg
)) < sizeof(msg
))
838 total
= DoWrite(buffer
, nbytes
);
843 msg
.sig
[0] = (unsigned char) 0xed;
844 msg
.sig
[1] = (unsigned char) 0xfe;
845 msg
.sig
[2] = (unsigned char) 0xad;
846 msg
.sig
[3] = (unsigned char) 0xde;
850 msg
.len
[3] = (char) 0;
852 if ((DoWrite(&msg
, sizeof(msg
))) < sizeof(msg
))
866 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
869 Pushback(buffer
, nbytes
);
877 wxSocketBase
& wxSocketBase::Discard()
879 char *buffer
= new char[MAX_DISCARD_SIZE
];
886 SetFlags(wxSOCKET_NOWAIT
);
890 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
893 while (ret
== MAX_DISCARD_SIZE
);
899 // Allow read events again
905 // --------------------------------------------------------------------------
907 // --------------------------------------------------------------------------
910 * Polls the socket to determine its status. This function will
911 * check for the events specified in the 'flags' parameter, and
912 * it will return a mask indicating which operations can be
913 * performed. This function won't block, regardless of the
914 * mode (blocking | nonblocking) of the socket.
916 GSocketEventFlags
GSocketBase::Select(GSocketEventFlags flags
)
920 GSocketEventFlags result
= 0;
927 return (GSOCK_LOST_FLAG
& flags
);
929 /* Do not use a static struct, Linux can garble it */
934 wxFD_ZERO(&writefds
);
935 wxFD_ZERO(&exceptfds
);
936 wxFD_SET(m_fd
, &readfds
);
937 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
938 wxFD_SET(m_fd
, &writefds
);
939 wxFD_SET(m_fd
, &exceptfds
);
941 /* Check 'sticky' CONNECTION flag first */
942 result
|= GSOCK_CONNECTION_FLAG
& m_detected
;
944 /* If we have already detected a LOST event, then don't try
945 * to do any further processing.
947 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
949 m_establishing
= false;
950 return (GSOCK_LOST_FLAG
& flags
);
954 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
956 /* What to do here? */
957 return (result
& flags
);
960 /* Check for exceptions and errors */
961 if (wxFD_ISSET(m_fd
, &exceptfds
))
963 m_establishing
= false;
964 m_detected
= GSOCK_LOST_FLAG
;
966 /* LOST event: Abort any further processing */
967 return (GSOCK_LOST_FLAG
& flags
);
970 /* Check for readability */
971 if (wxFD_ISSET(m_fd
, &readfds
))
973 result
|= GSOCK_INPUT_FLAG
;
975 if (m_server
&& m_stream
)
977 /* This is a TCP server socket that detected a connection.
978 While the INPUT_FLAG is also set, it doesn't matter on
979 this kind of sockets, as we can only Accept() from them. */
980 m_detected
|= GSOCK_CONNECTION_FLAG
;
984 /* Check for writability */
985 if (wxFD_ISSET(m_fd
, &writefds
))
987 if (m_establishing
&& !m_server
)
990 SOCKOPTLEN_T len
= sizeof(error
);
991 m_establishing
= false;
992 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
996 m_detected
= GSOCK_LOST_FLAG
;
998 /* LOST event: Abort any further processing */
999 return (GSOCK_LOST_FLAG
& flags
);
1003 m_detected
|= GSOCK_CONNECTION_FLAG
;
1008 result
|= GSOCK_OUTPUT_FLAG
;
1012 return (result
| m_detected
) & flags
;
1015 // All Wait functions poll the socket using GSocket_Select() to
1016 // check for the specified combination of conditions, until one
1017 // of these conditions become true, an error occurs, or the
1018 // timeout elapses. The polling loop runs the event loop so that
1019 // this won't block the GUI.
1022 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1024 wxCHECK_MSG( m_socket
, false, "can't wait on invalid socket" );
1026 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1027 m_interrupt
= false;
1030 // Use either the provided timeout or the default timeout value associated
1031 // with this socket.
1033 // TODO: allow waiting forever, see #9443
1034 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1035 : seconds
* 1000 + milliseconds
;
1036 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1038 // Get the active event loop which we'll use for the message dispatching
1039 // when running in the main thread
1040 wxEventLoopBase
*eventLoop
;
1041 if ( wxIsMainThread() )
1043 eventLoop
= wxEventLoop::GetActive();
1045 else // in worker thread
1047 // We never dispatch messages from threads other than the main one.
1051 // Wait in an active polling loop: notice that the loop is executed at
1052 // least once, even if timeout is 0 (i.e. polling).
1053 bool gotEvent
= false;
1056 // We always stop waiting when the connection is lost as it doesn't
1057 // make sense to continue further, even if GSOCK_LOST_FLAG is not
1058 // specified in flags to wait for.
1059 const GSocketEventFlags
1060 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
1062 // Incoming connection (server) or connection established (client)?
1063 if ( result
& GSOCK_CONNECTION_FLAG
)
1066 m_establishing
= false;
1071 // Data available or output buffer ready?
1072 if ( (result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
) )
1079 if ( result
& GSOCK_LOST_FLAG
)
1081 m_connected
= false;
1082 m_establishing
= false;
1083 if ( flags
& GSOCK_LOST_FLAG
)
1092 const wxMilliClock_t timeNow
= wxGetLocalTimeMillis();
1093 if ( timeNow
>= timeEnd
)
1098 // This function is only called if wxSOCKET_BLOCK flag was not used
1099 // and so we should dispatch the events if there is an event loop
1100 // capable of doing it.
1101 if ( eventLoop
->Pending() )
1102 eventLoop
->Dispatch();
1105 else // no event loop or waiting in another thread
1107 // We're busy waiting but at least give up the rest of our current
1111 #endif // wxUSE_THREADS
1117 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1119 return DoWait(seconds
, milliseconds
,
1122 GSOCK_CONNECTION_FLAG
|
1127 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1129 // Check pushback buffer before entering DoWait
1133 // Note that GSOCK_INPUT_LOST has to be explicitly passed to DoWait
1134 // because of the semantics of WaitForRead: a return value of true means
1135 // that a GSocket_Read call will return immediately, not that there is
1136 // actually data to read.
1137 return DoWait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
| GSOCK_LOST_FLAG
);
1141 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1143 return DoWait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
| GSOCK_LOST_FLAG
);
1146 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1148 return DoWait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
1151 // --------------------------------------------------------------------------
1153 // --------------------------------------------------------------------------
1156 // Get local or peer address
1159 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
1166 peer
= m_socket
->GetPeer();
1168 // copying a null address would just trigger an assert anyway
1173 addr_man
.SetAddress(peer
);
1174 GAddress_destroy(peer
);
1179 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1186 local
= m_socket
->GetLocal();
1187 addr_man
.SetAddress(local
);
1188 GAddress_destroy(local
);
1194 // Save and restore socket state
1197 void wxSocketBase::SaveState()
1199 wxSocketState
*state
;
1201 state
= new wxSocketState();
1203 state
->m_flags
= m_flags
;
1204 state
->m_notify
= m_notify
;
1205 state
->m_eventmask
= m_eventmask
;
1206 state
->m_clientData
= m_clientData
;
1208 m_states
.Append(state
);
1211 void wxSocketBase::RestoreState()
1213 wxList::compatibility_iterator node
;
1214 wxSocketState
*state
;
1216 node
= m_states
.GetLast();
1220 state
= (wxSocketState
*)node
->GetData();
1222 m_flags
= state
->m_flags
;
1223 m_notify
= state
->m_notify
;
1224 m_eventmask
= state
->m_eventmask
;
1225 m_clientData
= state
->m_clientData
;
1227 m_states
.Erase(node
);
1232 // Timeout and flags
1235 void wxSocketBase::SetTimeout(long seconds
)
1237 m_timeout
= seconds
;
1240 m_socket
->SetTimeout(m_timeout
* 1000);
1243 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1245 // Do some sanity checking on the flags used: not all values can be used
1247 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1248 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1249 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1250 "wxSOCKET_NOWAIT doesn't make sense" );
1256 // --------------------------------------------------------------------------
1258 // --------------------------------------------------------------------------
1260 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1262 switch(notification
)
1264 case wxSOCKET_CONNECTION
:
1265 m_establishing
= false;
1269 // If we are in the middle of a R/W operation, do not
1270 // propagate events to users. Also, filter 'late' events
1271 // which are no longer valid.
1273 case wxSOCKET_INPUT
:
1274 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
1278 case wxSOCKET_OUTPUT
:
1279 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
1284 m_connected
= false;
1285 m_establishing
= false;
1289 // Schedule the event
1291 wxSocketEventFlags flag
= 0;
1293 switch (notification
)
1295 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
1296 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
1297 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
1298 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
1300 wxLogWarning(_("wxSocket: unknown event!."));
1304 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1308 wxSocketEvent
event(m_id
);
1309 event
.m_event
= notification
;
1310 event
.m_clientData
= m_clientData
;
1311 event
.SetEventObject(this);
1313 m_handler
->AddPendingEvent(event
);
1318 void wxSocketBase::Notify(bool notify
)
1322 m_socket
->Notify(notify
);
1325 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1327 m_eventmask
= flags
;
1330 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1332 m_handler
= &handler
;
1336 // --------------------------------------------------------------------------
1338 // --------------------------------------------------------------------------
1340 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1344 if (m_unread
== NULL
)
1345 m_unread
= malloc(size
);
1350 tmp
= malloc(m_unrd_size
+ size
);
1351 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1357 m_unrd_size
+= size
;
1359 memcpy(m_unread
, buffer
, size
);
1362 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1364 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1369 if (size
> (m_unrd_size
-m_unrd_cur
))
1370 size
= m_unrd_size
-m_unrd_cur
;
1372 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1377 if (m_unrd_size
== m_unrd_cur
)
1390 // ==========================================================================
1392 // ==========================================================================
1394 // --------------------------------------------------------------------------
1396 // --------------------------------------------------------------------------
1398 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1399 wxSocketFlags flags
)
1400 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1402 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1404 m_socket
= GSocket::Create(*this);
1408 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1412 // Setup the socket as server
1413 m_socket
->Notify(m_notify
);
1414 m_socket
->SetLocal(addr_man
.GetAddress());
1416 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1417 m_socket
->SetReusable();
1419 if (GetFlags() & wxSOCKET_BROADCAST
) {
1420 m_socket
->SetBroadcast();
1422 if (GetFlags() & wxSOCKET_NOBIND
) {
1423 m_socket
->DontDoBind();
1426 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1431 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1435 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_socket
->m_fd
);
1438 // --------------------------------------------------------------------------
1440 // --------------------------------------------------------------------------
1442 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1447 // If wait == false, then the call should be nonblocking.
1448 // When we are finished, we put the socket to blocking mode
1450 wxSocketUnblocker
unblock(m_socket
, !wait
);
1451 sock
.m_socket
= m_socket
->WaitConnection(sock
);
1453 if ( !sock
.m_socket
)
1456 sock
.m_type
= wxSOCKET_BASE
;
1457 sock
.m_connected
= true;
1462 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1464 wxSocketBase
* sock
= new wxSocketBase();
1466 sock
->SetFlags(m_flags
);
1468 if (!AcceptWith(*sock
, wait
))
1477 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1479 return DoWait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1482 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1484 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1486 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1494 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1497 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1499 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1507 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1509 GAddress
* la
= local
.GetAddress();
1511 // If the address is valid, save it for use when we call Connect
1512 if (la
&& la
->m_addr
)
1514 m_localAddress
= local
;
1522 // ==========================================================================
1524 // ==========================================================================
1526 // --------------------------------------------------------------------------
1528 // --------------------------------------------------------------------------
1530 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1531 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1533 m_initialRecvBufferSize
=
1534 m_initialSendBufferSize
= -1;
1537 wxSocketClient::~wxSocketClient()
1541 // --------------------------------------------------------------------------
1543 // --------------------------------------------------------------------------
1545 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1546 const wxSockAddress
* local
,
1551 // Shutdown and destroy the socket
1556 m_socket
= GSocket::Create(*this);
1557 m_connected
= false;
1558 m_establishing
= false;
1563 // If wait == false, then the call should be nonblocking. When we are
1564 // finished, we put the socket to blocking mode again.
1565 wxSocketUnblocker
unblock(m_socket
, !wait
);
1567 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1568 if (GetFlags() & wxSOCKET_REUSEADDR
)
1570 m_socket
->SetReusable();
1572 if (GetFlags() & wxSOCKET_BROADCAST
)
1574 m_socket
->SetBroadcast();
1576 if (GetFlags() & wxSOCKET_NOBIND
)
1578 m_socket
->DontDoBind();
1581 // If no local address was passed and one has been set, use the one that was Set
1582 if (!local
&& m_localAddress
.GetAddress())
1584 local
= &m_localAddress
;
1587 // Bind to the local IP address and port, when provided
1590 GAddress
* la
= local
->GetAddress();
1592 if (la
&& la
->m_addr
)
1593 m_socket
->SetLocal(la
);
1596 #if defined(__WXMSW__) || defined(__WXGTK__)
1597 m_socket
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1600 m_socket
->SetPeer(addr_man
.GetAddress());
1601 const GSocketError err
= m_socket
->Connect(GSOCK_STREAMED
);
1603 //this will register for callbacks - must be called after m_socket->m_fd was initialized
1604 m_socket
->Notify(m_notify
);
1606 if (err
!= GSOCK_NOERROR
)
1608 if (err
== GSOCK_WOULDBLOCK
)
1609 m_establishing
= true;
1618 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1620 return DoConnect(addr_man
, NULL
, wait
);
1623 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1624 const wxSockAddress
& local
,
1627 return DoConnect(addr_man
, &local
, wait
);
1630 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1634 // this happens if the initial attempt to connect succeeded without
1639 wxCHECK_MSG( m_establishing
&& m_socket
, false,
1640 "No connection establishment attempt in progress" );
1642 // we must specify GSOCK_LOST_FLAG here explicitly because we must return
1643 // true if the connection establishment process is finished, whether it is
1644 // over because we successfully connected or because we were not able to
1646 return DoWait(seconds
, milliseconds
,
1647 GSOCK_CONNECTION_FLAG
| GSOCK_LOST_FLAG
);
1650 // ==========================================================================
1652 // ==========================================================================
1654 /* NOTE: experimental stuff - might change */
1656 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1657 wxSocketFlags flags
)
1658 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1660 // Create the socket
1661 m_socket
= GSocket::Create(*this);
1666 m_socket
->Notify(m_notify
);
1667 // Setup the socket as non connection oriented
1668 m_socket
->SetLocal(addr
.GetAddress());
1669 if (flags
& wxSOCKET_REUSEADDR
)
1671 m_socket
->SetReusable();
1673 if (GetFlags() & wxSOCKET_BROADCAST
)
1675 m_socket
->SetBroadcast();
1677 if (GetFlags() & wxSOCKET_NOBIND
)
1679 m_socket
->DontDoBind();
1681 if ( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1688 // Initialize all stuff
1689 m_connected
= false;
1690 m_establishing
= false;
1693 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1702 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1706 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1708 m_socket
->SetPeer(addr
.GetAddress());
1713 // ==========================================================================
1715 // ==========================================================================
1717 class wxSocketModule
: public wxModule
1720 virtual bool OnInit()
1722 // wxSocketBase will call GSocket_Init() itself when/if needed
1726 virtual void OnExit()
1728 if ( wxSocketBase::IsInitialized() )
1729 wxSocketBase::Shutdown();
1733 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1736 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1738 #endif // wxUSE_SOCKETS