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
)
235 m_timeout
.tv_sec
= (millis
/ 1000);
236 m_timeout
.tv_usec
= (millis
% 1000) * 1000;
242 void GSocketBase::NotifyOnStateChange(GSocketEvent event
)
244 // GSocketEvent and wxSocketNotify enums have the same elements with the
246 m_wxsocket
->OnRequest(static_cast<wxSocketNotify
>(event
));
249 /* Address handling */
255 * Set or get the local or peer address for this socket. The 'set'
256 * functions return GSOCK_NOERROR on success, an error code otherwise.
257 * The 'get' functions return a pointer to a GAddress object on success,
258 * or NULL otherwise, in which case they set the error code of the
259 * corresponding GSocket.
262 * GSOCK_INVSOCK - the socket is not valid.
263 * GSOCK_INVADDR - the address is not valid.
265 GSocketError
GSocketBase::SetLocal(GAddress
*address
)
267 /* the socket must be initialized, or it must be a server */
268 if (m_fd
!= INVALID_SOCKET
&& !m_server
)
270 m_error
= GSOCK_INVSOCK
;
271 return GSOCK_INVSOCK
;
275 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
277 m_error
= GSOCK_INVADDR
;
278 return GSOCK_INVADDR
;
282 GAddress_destroy(m_local
);
284 m_local
= GAddress_copy(address
);
286 return GSOCK_NOERROR
;
289 GSocketError
GSocketBase::SetPeer(GAddress
*address
)
292 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
294 m_error
= GSOCK_INVADDR
;
295 return GSOCK_INVADDR
;
299 GAddress_destroy(m_peer
);
301 m_peer
= GAddress_copy(address
);
303 return GSOCK_NOERROR
;
306 GAddress
*GSocketBase::GetLocal()
310 WX_SOCKLEN_T size
= sizeof(addr
);
313 /* try to get it from the m_local var first */
315 return GAddress_copy(m_local
);
317 /* else, if the socket is initialized, try getsockname */
318 if (m_fd
== INVALID_SOCKET
)
320 m_error
= GSOCK_INVSOCK
;
324 if (getsockname(m_fd
, (sockaddr
*)&addr
, &size
) == SOCKET_ERROR
)
326 m_error
= GSOCK_IOERR
;
330 /* got a valid address from getsockname, create a GAddress object */
331 if ((address
= GAddress_new()) == NULL
)
333 m_error
= GSOCK_MEMERR
;
337 if ((err
= _GAddress_translate_from(address
, (sockaddr
*)&addr
, size
)) != GSOCK_NOERROR
)
339 GAddress_destroy(address
);
347 GAddress
*GSocketBase::GetPeer()
349 /* try to get it from the m_peer var */
351 return GAddress_copy(m_peer
);
356 // ==========================================================================
358 // ==========================================================================
360 // --------------------------------------------------------------------------
361 // Initialization and shutdown
362 // --------------------------------------------------------------------------
364 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
365 // to m_countInit with a crit section
366 size_t wxSocketBase::m_countInit
= 0;
368 bool wxSocketBase::IsInitialized()
370 return m_countInit
> 0;
373 bool wxSocketBase::Initialize()
375 if ( !m_countInit
++ )
377 if ( !GSocket_Init() )
388 void wxSocketBase::Shutdown()
390 // we should be initialized
391 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
392 if ( --m_countInit
== 0 )
398 // --------------------------------------------------------------------------
400 // --------------------------------------------------------------------------
402 void wxSocketBase::Init()
405 m_type
= wxSOCKET_UNINIT
;
417 m_beingDeleted
= false;
431 if ( !IsInitialized() )
433 // this Initialize() will be undone by wxSocketModule::OnExit(), all
434 // the other calls to it should be matched by a call to Shutdown()
439 wxSocketBase::wxSocketBase()
444 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
453 wxSocketBase::~wxSocketBase()
455 // Just in case the app called Destroy() *and* then deleted the socket
456 // immediately: don't leave dangling pointers.
457 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
459 traits
->RemoveFromPendingDelete(this);
461 // Shutdown and close the socket
465 // Destroy the GSocket object
469 // Free the pushback buffer
474 bool wxSocketBase::Destroy()
476 // Delayed destruction: the socket will be deleted during the next idle
477 // loop iteration. This ensures that all pending events have been
479 m_beingDeleted
= true;
481 // Shutdown and close the socket
484 // Supress events from now on
487 // schedule this object for deletion
488 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
491 // let the traits object decide what to do with us
492 traits
->ScheduleForDestroy(this);
494 else // no app or no traits
496 // in wxBase we might have no app object at all, don't leak memory
503 // --------------------------------------------------------------------------
505 // --------------------------------------------------------------------------
507 // The following IO operations update m_error and m_lcount:
508 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
510 // TODO: Should Connect, Accept and AcceptWith update m_error?
512 bool wxSocketBase::Close()
514 // Interrupt pending waits
518 m_socket
->Shutdown();
521 m_establishing
= false;
525 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
530 m_lcount
= DoRead(buffer
, nbytes
);
532 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
533 if (m_flags
& wxSOCKET_WAITALL
)
534 m_error
= (m_lcount
!= nbytes
);
536 m_error
= (m_lcount
== 0);
538 // Allow read events from now on
544 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
546 // We use pointer arithmetic here which doesn't work with void pointers.
547 char *buffer
= static_cast<char *>(buffer_
);
549 // Try the push back buffer first, even before checking whether the socket
550 // is valid to allow reading previously pushed back data from an already
552 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
556 // If it's indeed closed or if read everything, there is nothing more to do.
557 if ( !m_socket
|| !nbytes
)
560 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
563 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
564 // polling the socket and don't block at all.
565 if ( m_flags
& wxSOCKET_NOWAIT
)
567 wxSocketUnblocker
unblock(m_socket
);
568 int ret
= m_socket
->Read(buffer
, nbytes
);
574 else // blocking socket
578 // Wait until socket becomes ready for reading dispatching the GUI
579 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
580 // specified to disable this.
581 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
584 const int ret
= m_socket
->Read(buffer
, nbytes
);
587 // for connection-oriented (e.g. TCP) sockets we can only read
588 // 0 bytes if the other end has been closed, and for
589 // connectionless ones (UDP) this flag doesn't make sense
590 // anyhow so we can set it to true too without doing any harm
597 // this will be always interpreted as error by Read()
603 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
604 // something and we don't need to wait for all nbytes bytes to be
606 if ( !(m_flags
& wxSOCKET_WAITALL
) )
609 // Otherwise continue reading until we do read everything.
621 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
623 wxUint32 len
, len2
, sig
, total
;
628 unsigned char sig
[4];
629 unsigned char len
[4];
638 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
640 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
643 sig
= (wxUint32
)msg
.sig
[0];
644 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
645 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
646 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
648 if (sig
!= 0xfeeddead)
650 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
654 len
= (wxUint32
)msg
.len
[0];
655 len
|= (wxUint32
)(msg
.len
[1] << 8);
656 len
|= (wxUint32
)(msg
.len
[2] << 16);
657 len
|= (wxUint32
)(msg
.len
[3] << 24);
667 // Don't attempt to read if the msg was zero bytes long.
670 total
= DoRead(buffer
, len
);
678 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
681 // NOTE: discarded bytes don't add to m_lcount.
684 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
685 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
686 len2
-= (wxUint32
)discard_len
;
688 while ((discard_len
> 0) && len2
);
690 delete [] discard_buffer
;
695 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
698 sig
= (wxUint32
)msg
.sig
[0];
699 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
700 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
701 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
703 if (sig
!= 0xdeadfeed)
705 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
721 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
726 m_lcount
= DoRead(buffer
, nbytes
);
727 Pushback(buffer
, m_lcount
);
729 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
730 if (m_flags
& wxSOCKET_WAITALL
)
731 m_error
= (m_lcount
!= nbytes
);
733 m_error
= (m_lcount
== 0);
735 // Allow read events again
741 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
746 m_lcount
= DoWrite(buffer
, nbytes
);
748 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
749 if (m_flags
& wxSOCKET_WAITALL
)
750 m_error
= (m_lcount
!= nbytes
);
752 m_error
= (m_lcount
== 0);
754 // Allow write events again
760 // This function is a mirror image of DoRead() except that it doesn't use the
761 // push back buffer, please see comments there
762 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
764 const char *buffer
= static_cast<const char *>(buffer_
);
766 // Return if there is nothing to read or the socket is (already?) closed.
767 if ( !m_socket
|| !nbytes
)
770 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
773 if ( m_flags
& wxSOCKET_NOWAIT
)
775 wxSocketUnblocker
unblock(m_socket
);
776 const int ret
= m_socket
->Write(buffer
, nbytes
);
780 else // blocking socket
784 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
787 const int ret
= m_socket
->Write(buffer
, nbytes
);
798 if ( !(m_flags
& wxSOCKET_WAITALL
) )
812 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
818 unsigned char sig
[4];
819 unsigned char len
[4];
827 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
829 msg
.sig
[0] = (unsigned char) 0xad;
830 msg
.sig
[1] = (unsigned char) 0xde;
831 msg
.sig
[2] = (unsigned char) 0xed;
832 msg
.sig
[3] = (unsigned char) 0xfe;
834 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
835 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
836 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
837 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
839 if (DoWrite(&msg
, sizeof(msg
)) < sizeof(msg
))
842 total
= DoWrite(buffer
, nbytes
);
847 msg
.sig
[0] = (unsigned char) 0xed;
848 msg
.sig
[1] = (unsigned char) 0xfe;
849 msg
.sig
[2] = (unsigned char) 0xad;
850 msg
.sig
[3] = (unsigned char) 0xde;
854 msg
.len
[3] = (char) 0;
856 if ((DoWrite(&msg
, sizeof(msg
))) < sizeof(msg
))
870 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
873 Pushback(buffer
, nbytes
);
881 wxSocketBase
& wxSocketBase::Discard()
883 char *buffer
= new char[MAX_DISCARD_SIZE
];
890 SetFlags(wxSOCKET_NOWAIT
);
894 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
897 while (ret
== MAX_DISCARD_SIZE
);
903 // Allow read events again
909 // --------------------------------------------------------------------------
911 // --------------------------------------------------------------------------
914 * Polls the socket to determine its status. This function will
915 * check for the events specified in the 'flags' parameter, and
916 * it will return a mask indicating which operations can be
917 * performed. This function won't block, regardless of the
918 * mode (blocking | nonblocking) of the socket.
920 GSocketEventFlags
GSocketBase::Select(GSocketEventFlags flags
)
924 GSocketEventFlags result
= 0;
931 return (GSOCK_LOST_FLAG
& flags
);
933 /* Do not use a static struct, Linux can garble it */
938 wxFD_ZERO(&writefds
);
939 wxFD_ZERO(&exceptfds
);
940 wxFD_SET(m_fd
, &readfds
);
941 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
942 wxFD_SET(m_fd
, &writefds
);
943 wxFD_SET(m_fd
, &exceptfds
);
945 /* Check 'sticky' CONNECTION flag first */
946 result
|= GSOCK_CONNECTION_FLAG
& m_detected
;
948 /* If we have already detected a LOST event, then don't try
949 * to do any further processing.
951 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
953 m_establishing
= false;
954 return (GSOCK_LOST_FLAG
& flags
);
958 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
960 /* What to do here? */
961 return (result
& flags
);
964 /* Check for exceptions and errors */
965 if (wxFD_ISSET(m_fd
, &exceptfds
))
967 m_establishing
= false;
968 m_detected
= GSOCK_LOST_FLAG
;
970 /* LOST event: Abort any further processing */
971 return (GSOCK_LOST_FLAG
& flags
);
974 /* Check for readability */
975 if (wxFD_ISSET(m_fd
, &readfds
))
977 result
|= GSOCK_INPUT_FLAG
;
979 if (m_server
&& m_stream
)
981 /* This is a TCP server socket that detected a connection.
982 While the INPUT_FLAG is also set, it doesn't matter on
983 this kind of sockets, as we can only Accept() from them. */
984 m_detected
|= GSOCK_CONNECTION_FLAG
;
988 /* Check for writability */
989 if (wxFD_ISSET(m_fd
, &writefds
))
991 if (m_establishing
&& !m_server
)
994 SOCKOPTLEN_T len
= sizeof(error
);
995 m_establishing
= false;
996 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
1000 m_detected
= GSOCK_LOST_FLAG
;
1002 /* LOST event: Abort any further processing */
1003 return (GSOCK_LOST_FLAG
& flags
);
1007 m_detected
|= GSOCK_CONNECTION_FLAG
;
1012 result
|= GSOCK_OUTPUT_FLAG
;
1016 return (result
| m_detected
) & flags
;
1019 // All Wait functions poll the socket using GSocket_Select() to
1020 // check for the specified combination of conditions, until one
1021 // of these conditions become true, an error occurs, or the
1022 // timeout elapses. The polling loop runs the event loop so that
1023 // this won't block the GUI.
1026 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
1028 wxCHECK_MSG( m_socket
, false, "can't wait on invalid socket" );
1030 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1031 m_interrupt
= false;
1034 // Use either the provided timeout or the default timeout value associated
1035 // with this socket.
1037 // TODO: allow waiting forever, see #9443
1038 const long timeout
= seconds
== -1 ? m_timeout
* 1000
1039 : seconds
* 1000 + milliseconds
;
1040 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
1042 // Get the active event loop which we'll use for the message dispatching
1043 // when running in the main thread
1044 wxEventLoopBase
*eventLoop
;
1045 if ( wxIsMainThread() )
1047 eventLoop
= wxEventLoop::GetActive();
1049 else // in worker thread
1051 // We never dispatch messages from threads other than the main one.
1055 // Wait in an active polling loop: notice that the loop is executed at
1056 // least once, even if timeout is 0 (i.e. polling).
1057 bool gotEvent
= false;
1060 // We always stop waiting when the connection is lost as it doesn't
1061 // make sense to continue further, even if GSOCK_LOST_FLAG is not
1062 // specified in flags to wait for.
1063 const GSocketEventFlags
1064 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
1066 // Incoming connection (server) or connection established (client)?
1067 if ( result
& GSOCK_CONNECTION_FLAG
)
1070 m_establishing
= false;
1075 // Data available or output buffer ready?
1076 if ( (result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
) )
1083 if ( result
& GSOCK_LOST_FLAG
)
1085 m_connected
= false;
1086 m_establishing
= false;
1087 if ( flags
& GSOCK_LOST_FLAG
)
1096 const wxMilliClock_t timeNow
= wxGetLocalTimeMillis();
1097 if ( timeNow
>= timeEnd
)
1102 // This function is only called if wxSOCKET_BLOCK flag was not used
1103 // and so we should dispatch the events if there is an event loop
1104 // capable of doing it.
1105 if ( eventLoop
->Pending() )
1106 eventLoop
->Dispatch();
1109 else // no event loop or waiting in another thread
1111 // We're busy waiting but at least give up the rest of our current
1115 #endif // wxUSE_THREADS
1121 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
1123 return DoWait(seconds
, milliseconds
,
1126 GSOCK_CONNECTION_FLAG
|
1131 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
1133 // Check pushback buffer before entering DoWait
1137 // Note that GSOCK_INPUT_LOST has to be explicitly passed to DoWait
1138 // because of the semantics of WaitForRead: a return value of true means
1139 // that a GSocket_Read call will return immediately, not that there is
1140 // actually data to read.
1141 return DoWait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
| GSOCK_LOST_FLAG
);
1145 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
1147 return DoWait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
| GSOCK_LOST_FLAG
);
1150 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
1152 return DoWait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
1155 // --------------------------------------------------------------------------
1157 // --------------------------------------------------------------------------
1160 // Get local or peer address
1163 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
1170 peer
= m_socket
->GetPeer();
1172 // copying a null address would just trigger an assert anyway
1177 addr_man
.SetAddress(peer
);
1178 GAddress_destroy(peer
);
1183 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1190 local
= m_socket
->GetLocal();
1191 addr_man
.SetAddress(local
);
1192 GAddress_destroy(local
);
1198 // Save and restore socket state
1201 void wxSocketBase::SaveState()
1203 wxSocketState
*state
;
1205 state
= new wxSocketState();
1207 state
->m_flags
= m_flags
;
1208 state
->m_notify
= m_notify
;
1209 state
->m_eventmask
= m_eventmask
;
1210 state
->m_clientData
= m_clientData
;
1212 m_states
.Append(state
);
1215 void wxSocketBase::RestoreState()
1217 wxList::compatibility_iterator node
;
1218 wxSocketState
*state
;
1220 node
= m_states
.GetLast();
1224 state
= (wxSocketState
*)node
->GetData();
1226 m_flags
= state
->m_flags
;
1227 m_notify
= state
->m_notify
;
1228 m_eventmask
= state
->m_eventmask
;
1229 m_clientData
= state
->m_clientData
;
1231 m_states
.Erase(node
);
1236 // Timeout and flags
1239 void wxSocketBase::SetTimeout(long seconds
)
1241 m_timeout
= seconds
;
1244 m_socket
->SetTimeout(m_timeout
* 1000);
1247 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1249 // Do some sanity checking on the flags used: not all values can be used
1251 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1252 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1253 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1254 "wxSOCKET_NOWAIT doesn't make sense" );
1260 // --------------------------------------------------------------------------
1262 // --------------------------------------------------------------------------
1264 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1266 switch(notification
)
1268 case wxSOCKET_CONNECTION
:
1269 m_establishing
= false;
1273 // If we are in the middle of a R/W operation, do not
1274 // propagate events to users. Also, filter 'late' events
1275 // which are no longer valid.
1277 case wxSOCKET_INPUT
:
1278 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
1282 case wxSOCKET_OUTPUT
:
1283 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
1288 m_connected
= false;
1289 m_establishing
= false;
1293 // Schedule the event
1295 wxSocketEventFlags flag
= 0;
1297 switch (notification
)
1299 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
1300 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
1301 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
1302 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
1304 wxLogWarning(_("wxSocket: unknown event!."));
1308 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1312 wxSocketEvent
event(m_id
);
1313 event
.m_event
= notification
;
1314 event
.m_clientData
= m_clientData
;
1315 event
.SetEventObject(this);
1317 m_handler
->AddPendingEvent(event
);
1322 void wxSocketBase::Notify(bool notify
)
1326 m_socket
->Notify(notify
);
1329 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1331 m_eventmask
= flags
;
1334 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1336 m_handler
= &handler
;
1340 // --------------------------------------------------------------------------
1342 // --------------------------------------------------------------------------
1344 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1348 if (m_unread
== NULL
)
1349 m_unread
= malloc(size
);
1354 tmp
= malloc(m_unrd_size
+ size
);
1355 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1361 m_unrd_size
+= size
;
1363 memcpy(m_unread
, buffer
, size
);
1366 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1368 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1373 if (size
> (m_unrd_size
-m_unrd_cur
))
1374 size
= m_unrd_size
-m_unrd_cur
;
1376 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1381 if (m_unrd_size
== m_unrd_cur
)
1394 // ==========================================================================
1396 // ==========================================================================
1398 // --------------------------------------------------------------------------
1400 // --------------------------------------------------------------------------
1402 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1403 wxSocketFlags flags
)
1404 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1406 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1408 m_socket
= GSocket::Create(*this);
1412 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1416 // Setup the socket as server
1417 m_socket
->Notify(m_notify
);
1418 m_socket
->SetLocal(addr_man
.GetAddress());
1420 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1421 m_socket
->SetReusable();
1423 if (GetFlags() & wxSOCKET_BROADCAST
) {
1424 m_socket
->SetBroadcast();
1426 if (GetFlags() & wxSOCKET_NOBIND
) {
1427 m_socket
->DontDoBind();
1430 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1435 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1439 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_socket
->m_fd
);
1442 // --------------------------------------------------------------------------
1444 // --------------------------------------------------------------------------
1446 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1451 // If wait == false, then the call should be nonblocking.
1452 // When we are finished, we put the socket to blocking mode
1454 wxSocketUnblocker
unblock(m_socket
, !wait
);
1455 sock
.m_socket
= m_socket
->WaitConnection(sock
);
1457 if ( !sock
.m_socket
)
1460 sock
.m_type
= wxSOCKET_BASE
;
1461 sock
.m_connected
= true;
1466 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1468 wxSocketBase
* sock
= new wxSocketBase();
1470 sock
->SetFlags(m_flags
);
1472 if (!AcceptWith(*sock
, wait
))
1481 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1483 return DoWait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1486 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1488 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1490 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1498 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1501 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1503 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1511 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1513 GAddress
* la
= local
.GetAddress();
1515 // If the address is valid, save it for use when we call Connect
1516 if (la
&& la
->m_addr
)
1518 m_localAddress
= local
;
1526 // ==========================================================================
1528 // ==========================================================================
1530 // --------------------------------------------------------------------------
1532 // --------------------------------------------------------------------------
1534 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1535 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1537 m_initialRecvBufferSize
=
1538 m_initialSendBufferSize
= -1;
1541 wxSocketClient::~wxSocketClient()
1545 // --------------------------------------------------------------------------
1547 // --------------------------------------------------------------------------
1549 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1550 const wxSockAddress
* local
,
1555 // Shutdown and destroy the socket
1560 m_socket
= GSocket::Create(*this);
1561 m_connected
= false;
1562 m_establishing
= false;
1567 // If wait == false, then the call should be nonblocking. When we are
1568 // finished, we put the socket to blocking mode again.
1569 wxSocketUnblocker
unblock(m_socket
, !wait
);
1571 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1572 if (GetFlags() & wxSOCKET_REUSEADDR
)
1574 m_socket
->SetReusable();
1576 if (GetFlags() & wxSOCKET_BROADCAST
)
1578 m_socket
->SetBroadcast();
1580 if (GetFlags() & wxSOCKET_NOBIND
)
1582 m_socket
->DontDoBind();
1585 // If no local address was passed and one has been set, use the one that was Set
1586 if (!local
&& m_localAddress
.GetAddress())
1588 local
= &m_localAddress
;
1591 // Bind to the local IP address and port, when provided
1594 GAddress
* la
= local
->GetAddress();
1596 if (la
&& la
->m_addr
)
1597 m_socket
->SetLocal(la
);
1600 #if defined(__WXMSW__) || defined(__WXGTK__)
1601 m_socket
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1604 m_socket
->SetPeer(addr_man
.GetAddress());
1605 const GSocketError err
= m_socket
->Connect(GSOCK_STREAMED
);
1607 //this will register for callbacks - must be called after m_socket->m_fd was initialized
1608 m_socket
->Notify(m_notify
);
1610 if (err
!= GSOCK_NOERROR
)
1612 if (err
== GSOCK_WOULDBLOCK
)
1613 m_establishing
= true;
1622 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1624 return DoConnect(addr_man
, NULL
, wait
);
1627 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1628 const wxSockAddress
& local
,
1631 return DoConnect(addr_man
, &local
, wait
);
1634 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1638 // this happens if the initial attempt to connect succeeded without
1643 wxCHECK_MSG( m_establishing
&& m_socket
, false,
1644 "No connection establishment attempt in progress" );
1646 // we must specify GSOCK_LOST_FLAG here explicitly because we must return
1647 // true if the connection establishment process is finished, whether it is
1648 // over because we successfully connected or because we were not able to
1650 return DoWait(seconds
, milliseconds
,
1651 GSOCK_CONNECTION_FLAG
| GSOCK_LOST_FLAG
);
1654 // ==========================================================================
1656 // ==========================================================================
1658 /* NOTE: experimental stuff - might change */
1660 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1661 wxSocketFlags flags
)
1662 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1664 // Create the socket
1665 m_socket
= GSocket::Create(*this);
1670 m_socket
->Notify(m_notify
);
1671 // Setup the socket as non connection oriented
1672 m_socket
->SetLocal(addr
.GetAddress());
1673 if (flags
& wxSOCKET_REUSEADDR
)
1675 m_socket
->SetReusable();
1677 if (GetFlags() & wxSOCKET_BROADCAST
)
1679 m_socket
->SetBroadcast();
1681 if (GetFlags() & wxSOCKET_NOBIND
)
1683 m_socket
->DontDoBind();
1685 if ( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1692 // Initialize all stuff
1693 m_connected
= false;
1694 m_establishing
= false;
1697 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1706 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1710 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1712 m_socket
->SetPeer(addr
.GetAddress());
1717 // ==========================================================================
1719 // ==========================================================================
1721 class wxSocketModule
: public wxModule
1724 virtual bool OnInit()
1726 // wxSocketBase will call GSocket_Init() itself when/if needed
1730 virtual void OnExit()
1732 if ( wxSocketBase::IsInitialized() )
1733 wxSocketBase::Shutdown();
1737 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1740 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1742 #endif // wxUSE_SOCKETS