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 // DLL options compatibility check:
47 WX_CHECK_BUILD_OPTIONS("wxNet")
49 // --------------------------------------------------------------------------
50 // macros and constants
51 // --------------------------------------------------------------------------
54 #define MAX_DISCARD_SIZE (10 * 1024)
56 #define wxTRACE_Socket _T("wxSocket")
58 // --------------------------------------------------------------------------
60 // --------------------------------------------------------------------------
62 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
63 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
64 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
65 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
66 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
68 // --------------------------------------------------------------------------
70 // --------------------------------------------------------------------------
72 class wxSocketState
: public wxObject
75 wxSocketFlags m_flags
;
76 wxSocketEventFlags m_eventmask
;
81 wxSocketState() : wxObject() {}
83 DECLARE_NO_COPY_CLASS(wxSocketState
)
86 // Conditionally make the socket non-blocking for the lifetime of this object.
87 class wxSocketUnblocker
90 wxSocketUnblocker(GSocket
*socket
, bool unblock
= true)
95 m_socket
->SetNonBlocking(true);
101 m_socket
->SetNonBlocking(false);
105 GSocket
* const m_socket
;
108 DECLARE_NO_COPY_CLASS(wxSocketUnblocker
)
111 // ============================================================================
113 // ============================================================================
115 GSocketManager
*GSocketManager::ms_manager
= NULL
;
118 void GSocketManager::Set(GSocketManager
*manager
)
120 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
122 ms_manager
= manager
;
126 void GSocketManager::Init()
128 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
131 Details: Initialize() creates a hidden window as a sink for socket
132 events, such as 'read completed'. wxMSW has only one message loop
133 for the main thread. If Initialize is called in a secondary thread,
134 the socket window will be created for the secondary thread, but
135 since there is no message loop on this thread, it will never
136 receive events and all socket operations will time out.
137 BTW, the main thread must not be stopped using sleep or block
138 on a semaphore (a bad idea in any case) or socket operations
141 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
142 the main thread. Because secondary threads do not have run loops,
143 adding event notifications to the "Current" loop would have no
144 effect at all, events would never fire.
146 wxASSERT_MSG( wxIsMainThread(),
147 "sockets must be initialized from the main thread" );
149 wxAppConsole
* const app
= wxAppConsole::GetInstance();
150 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
152 ms_manager
= app
->GetTraits()->GetSocketManager();
155 // ==========================================================================
157 // ==========================================================================
159 // --------------------------------------------------------------------------
160 // Initialization and shutdown
161 // --------------------------------------------------------------------------
163 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
164 // to m_countInit with a crit section
165 size_t wxSocketBase::m_countInit
= 0;
167 bool wxSocketBase::IsInitialized()
169 return m_countInit
> 0;
172 bool wxSocketBase::Initialize()
174 if ( !m_countInit
++ )
176 if ( !GSocket_Init() )
187 void wxSocketBase::Shutdown()
189 // we should be initialized
190 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
191 if ( --m_countInit
== 0 )
197 // --------------------------------------------------------------------------
199 // --------------------------------------------------------------------------
201 void wxSocketBase::Init()
204 m_type
= wxSOCKET_UNINIT
;
216 m_beingDeleted
= false;
230 if ( !IsInitialized() )
232 // this Initialize() will be undone by wxSocketModule::OnExit(), all
233 // the other calls to it should be matched by a call to Shutdown()
238 wxSocketBase::wxSocketBase()
243 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
252 wxSocketBase::~wxSocketBase()
254 // Just in case the app called Destroy() *and* then deleted the socket
255 // immediately: don't leave dangling pointers.
256 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
258 traits
->RemoveFromPendingDelete(this);
260 // Shutdown and close the socket
264 // Destroy the GSocket object
268 // Free the pushback buffer
273 bool wxSocketBase::Destroy()
275 // Delayed destruction: the socket will be deleted during the next idle
276 // loop iteration. This ensures that all pending events have been
278 m_beingDeleted
= true;
280 // Shutdown and close the socket
283 // Supress events from now on
286 // schedule this object for deletion
287 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
290 // let the traits object decide what to do with us
291 traits
->ScheduleForDestroy(this);
293 else // no app or no traits
295 // in wxBase we might have no app object at all, don't leak memory
302 // --------------------------------------------------------------------------
304 // --------------------------------------------------------------------------
306 // The following IO operations update m_error and m_lcount:
307 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
309 // TODO: Should Connect, Accept and AcceptWith update m_error?
311 bool wxSocketBase::Close()
313 // Interrupt pending waits
319 m_socket
->UnsetCallback(
323 GSOCK_CONNECTION_FLAG
326 // Shutdown the connection
327 m_socket
->Shutdown();
331 m_establishing
= false;
335 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
340 m_lcount
= DoRead(buffer
, nbytes
);
342 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
343 if (m_flags
& wxSOCKET_WAITALL
)
344 m_error
= (m_lcount
!= nbytes
);
346 m_error
= (m_lcount
== 0);
348 // Allow read events from now on
354 wxUint32
wxSocketBase::DoRead(void* buffer_
, wxUint32 nbytes
)
356 // We use pointer arithmetic here which doesn't work with void pointers.
357 char *buffer
= static_cast<char *>(buffer_
);
359 // Try the push back buffer first, even before checking whether the socket
360 // is valid to allow reading previously pushed back data from an already
362 wxUint32 total
= GetPushback(buffer
, nbytes
, false);
366 // If it's indeed closed or if read everything, there is nothing more to do.
367 if ( !m_socket
|| !nbytes
)
370 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
373 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
374 // polling the socket and don't block at all.
375 if ( m_flags
& wxSOCKET_NOWAIT
)
377 wxSocketUnblocker
unblock(m_socket
);
378 int ret
= m_socket
->Read(buffer
, nbytes
);
384 else // blocking socket
388 // Wait until socket becomes ready for reading dispatching the GUI
389 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
390 // specified to disable this.
391 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
394 const int ret
= m_socket
->Read(buffer
, nbytes
);
397 // for connection-oriented (e.g. TCP) sockets we can only read
398 // 0 bytes if the other end has been closed, and for
399 // connectionless ones (UDP) this flag doesn't make sense
400 // anyhow so we can set it to true too without doing any harm
407 // this will be always interpreted as error by Read()
413 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
414 // something and we don't need to wait for all nbytes bytes to be
416 if ( !(m_flags
& wxSOCKET_WAITALL
) )
419 // Otherwise continue reading until we do read everything.
431 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
433 wxUint32 len
, len2
, sig
, total
;
438 unsigned char sig
[4];
439 unsigned char len
[4];
448 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
450 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
453 sig
= (wxUint32
)msg
.sig
[0];
454 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
455 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
456 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
458 if (sig
!= 0xfeeddead)
460 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
464 len
= (wxUint32
)msg
.len
[0];
465 len
|= (wxUint32
)(msg
.len
[1] << 8);
466 len
|= (wxUint32
)(msg
.len
[2] << 16);
467 len
|= (wxUint32
)(msg
.len
[3] << 24);
477 // Don't attempt to read if the msg was zero bytes long.
480 total
= DoRead(buffer
, len
);
488 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
491 // NOTE: discarded bytes don't add to m_lcount.
494 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
495 discard_len
= DoRead(discard_buffer
, (wxUint32
)discard_len
);
496 len2
-= (wxUint32
)discard_len
;
498 while ((discard_len
> 0) && len2
);
500 delete [] discard_buffer
;
505 if (DoRead(&msg
, sizeof(msg
)) != sizeof(msg
))
508 sig
= (wxUint32
)msg
.sig
[0];
509 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
510 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
511 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
513 if (sig
!= 0xdeadfeed)
515 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
531 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
536 m_lcount
= DoRead(buffer
, nbytes
);
537 Pushback(buffer
, m_lcount
);
539 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
540 if (m_flags
& wxSOCKET_WAITALL
)
541 m_error
= (m_lcount
!= nbytes
);
543 m_error
= (m_lcount
== 0);
545 // Allow read events again
551 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
556 m_lcount
= DoWrite(buffer
, nbytes
);
558 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
559 if (m_flags
& wxSOCKET_WAITALL
)
560 m_error
= (m_lcount
!= nbytes
);
562 m_error
= (m_lcount
== 0);
564 // Allow write events again
570 // This function is a mirror image of DoRead() except that it doesn't use the
571 // push back buffer, please see comments there
572 wxUint32
wxSocketBase::DoWrite(const void *buffer_
, wxUint32 nbytes
)
574 const char *buffer
= static_cast<const char *>(buffer_
);
576 // Return if there is nothing to read or the socket is (already?) closed.
577 if ( !m_socket
|| !nbytes
)
580 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
583 if ( m_flags
& wxSOCKET_NOWAIT
)
585 wxSocketUnblocker
unblock(m_socket
);
586 const int ret
= m_socket
->Write(buffer
, nbytes
);
590 else // blocking socket
594 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
597 const int ret
= m_socket
->Write(buffer
, nbytes
);
608 if ( !(m_flags
& wxSOCKET_WAITALL
) )
622 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
628 unsigned char sig
[4];
629 unsigned char len
[4];
637 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
639 msg
.sig
[0] = (unsigned char) 0xad;
640 msg
.sig
[1] = (unsigned char) 0xde;
641 msg
.sig
[2] = (unsigned char) 0xed;
642 msg
.sig
[3] = (unsigned char) 0xfe;
644 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
645 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
646 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
647 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
649 if (DoWrite(&msg
, sizeof(msg
)) < sizeof(msg
))
652 total
= DoWrite(buffer
, nbytes
);
657 msg
.sig
[0] = (unsigned char) 0xed;
658 msg
.sig
[1] = (unsigned char) 0xfe;
659 msg
.sig
[2] = (unsigned char) 0xad;
660 msg
.sig
[3] = (unsigned char) 0xde;
664 msg
.len
[3] = (char) 0;
666 if ((DoWrite(&msg
, sizeof(msg
))) < sizeof(msg
))
680 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
683 Pushback(buffer
, nbytes
);
691 wxSocketBase
& wxSocketBase::Discard()
693 char *buffer
= new char[MAX_DISCARD_SIZE
];
700 SetFlags(wxSOCKET_NOWAIT
);
704 ret
= DoRead(buffer
, MAX_DISCARD_SIZE
);
707 while (ret
== MAX_DISCARD_SIZE
);
713 // Allow read events again
719 // --------------------------------------------------------------------------
721 // --------------------------------------------------------------------------
724 * Polls the socket to determine its status. This function will
725 * check for the events specified in the 'flags' parameter, and
726 * it will return a mask indicating which operations can be
727 * performed. This function won't block, regardless of the
728 * mode (blocking | nonblocking) of the socket.
730 GSocketEventFlags
GSocketBase::Select(GSocketEventFlags flags
)
734 GSocketEventFlags result
= 0;
741 return (GSOCK_LOST_FLAG
& flags
);
743 /* Do not use a static struct, Linux can garble it */
748 wxFD_ZERO(&writefds
);
749 wxFD_ZERO(&exceptfds
);
750 wxFD_SET(m_fd
, &readfds
);
751 if (flags
& GSOCK_OUTPUT_FLAG
|| flags
& GSOCK_CONNECTION_FLAG
)
752 wxFD_SET(m_fd
, &writefds
);
753 wxFD_SET(m_fd
, &exceptfds
);
755 /* Check 'sticky' CONNECTION flag first */
756 result
|= GSOCK_CONNECTION_FLAG
& m_detected
;
758 /* If we have already detected a LOST event, then don't try
759 * to do any further processing.
761 if ((m_detected
& GSOCK_LOST_FLAG
) != 0)
763 m_establishing
= false;
764 return (GSOCK_LOST_FLAG
& flags
);
768 if (select(m_fd
+ 1, &readfds
, &writefds
, &exceptfds
, &tv
) < 0)
770 /* What to do here? */
771 return (result
& flags
);
774 /* Check for exceptions and errors */
775 if (wxFD_ISSET(m_fd
, &exceptfds
))
777 m_establishing
= false;
778 m_detected
= GSOCK_LOST_FLAG
;
780 /* LOST event: Abort any further processing */
781 return (GSOCK_LOST_FLAG
& flags
);
784 /* Check for readability */
785 if (wxFD_ISSET(m_fd
, &readfds
))
787 result
|= GSOCK_INPUT_FLAG
;
789 if (m_server
&& m_stream
)
791 /* This is a TCP server socket that detected a connection.
792 While the INPUT_FLAG is also set, it doesn't matter on
793 this kind of sockets, as we can only Accept() from them. */
794 m_detected
|= GSOCK_CONNECTION_FLAG
;
798 /* Check for writability */
799 if (wxFD_ISSET(m_fd
, &writefds
))
801 if (m_establishing
&& !m_server
)
804 SOCKOPTLEN_T len
= sizeof(error
);
805 m_establishing
= false;
806 getsockopt(m_fd
, SOL_SOCKET
, SO_ERROR
, (char*)&error
, &len
);
810 m_detected
= GSOCK_LOST_FLAG
;
812 /* LOST event: Abort any further processing */
813 return (GSOCK_LOST_FLAG
& flags
);
817 m_detected
|= GSOCK_CONNECTION_FLAG
;
822 result
|= GSOCK_OUTPUT_FLAG
;
826 return (result
| m_detected
) & flags
;
829 // All Wait functions poll the socket using GSocket_Select() to
830 // check for the specified combination of conditions, until one
831 // of these conditions become true, an error occurs, or the
832 // timeout elapses. The polling loop runs the event loop so that
833 // this won't block the GUI.
836 wxSocketBase::DoWait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
838 wxCHECK_MSG( m_socket
, false, "can't wait on invalid socket" );
840 // This can be set to true from Interrupt() to exit this function a.s.a.p.
844 // Use either the provided timeout or the default timeout value associated
847 // TODO: allow waiting forever, see #9443
848 const long timeout
= seconds
== -1 ? m_timeout
* 1000
849 : seconds
* 1000 + milliseconds
;
850 const wxMilliClock_t timeEnd
= wxGetLocalTimeMillis() + timeout
;
852 // Get the active event loop which we'll use for the message dispatching
853 // when running in the main thread
854 wxEventLoopBase
*eventLoop
;
855 if ( wxIsMainThread() )
857 eventLoop
= wxEventLoop::GetActive();
859 else // in worker thread
861 // We never dispatch messages from threads other than the main one.
865 // Wait in an active polling loop: notice that the loop is executed at
866 // least once, even if timeout is 0 (i.e. polling).
867 bool gotEvent
= false;
870 // We always stop waiting when the connection is lost as it doesn't
871 // make sense to continue further, even if GSOCK_LOST_FLAG is not
872 // specified in flags to wait for.
873 const GSocketEventFlags
874 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
876 // Incoming connection (server) or connection established (client)?
877 if ( result
& GSOCK_CONNECTION_FLAG
)
880 m_establishing
= false;
885 // Data available or output buffer ready?
886 if ( (result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
) )
893 if ( result
& GSOCK_LOST_FLAG
)
896 m_establishing
= false;
897 if ( flags
& GSOCK_LOST_FLAG
)
906 const wxMilliClock_t timeNow
= wxGetLocalTimeMillis();
907 if ( timeNow
>= timeEnd
)
912 // This function is only called if wxSOCKET_BLOCK flag was not used
913 // and so we should dispatch the events if there is an event loop
914 // capable of doing it.
915 if ( eventLoop
->Pending() )
916 eventLoop
->Dispatch();
919 else // no event loop or waiting in another thread
921 // We're busy waiting but at least give up the rest of our current
925 #endif // wxUSE_THREADS
931 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
933 return DoWait(seconds
, milliseconds
,
936 GSOCK_CONNECTION_FLAG
|
941 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
943 // Check pushback buffer before entering DoWait
947 // Note that GSOCK_INPUT_LOST has to be explicitly passed to DoWait
948 // because of the semantics of WaitForRead: a return value of true means
949 // that a GSocket_Read call will return immediately, not that there is
950 // actually data to read.
951 return DoWait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
| GSOCK_LOST_FLAG
);
955 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
957 return DoWait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
| GSOCK_LOST_FLAG
);
960 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
962 return DoWait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
965 // --------------------------------------------------------------------------
967 // --------------------------------------------------------------------------
970 // Get local or peer address
973 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
980 peer
= m_socket
->GetPeer();
982 // copying a null address would just trigger an assert anyway
987 addr_man
.SetAddress(peer
);
988 GAddress_destroy(peer
);
993 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
1000 local
= m_socket
->GetLocal();
1001 addr_man
.SetAddress(local
);
1002 GAddress_destroy(local
);
1008 // Save and restore socket state
1011 void wxSocketBase::SaveState()
1013 wxSocketState
*state
;
1015 state
= new wxSocketState();
1017 state
->m_flags
= m_flags
;
1018 state
->m_notify
= m_notify
;
1019 state
->m_eventmask
= m_eventmask
;
1020 state
->m_clientData
= m_clientData
;
1022 m_states
.Append(state
);
1025 void wxSocketBase::RestoreState()
1027 wxList::compatibility_iterator node
;
1028 wxSocketState
*state
;
1030 node
= m_states
.GetLast();
1034 state
= (wxSocketState
*)node
->GetData();
1036 m_flags
= state
->m_flags
;
1037 m_notify
= state
->m_notify
;
1038 m_eventmask
= state
->m_eventmask
;
1039 m_clientData
= state
->m_clientData
;
1041 m_states
.Erase(node
);
1046 // Timeout and flags
1049 void wxSocketBase::SetTimeout(long seconds
)
1051 m_timeout
= seconds
;
1054 m_socket
->SetTimeout(m_timeout
* 1000);
1057 void wxSocketBase::SetFlags(wxSocketFlags flags
)
1059 // Do some sanity checking on the flags used: not all values can be used
1061 wxASSERT_MSG( !(flags
& wxSOCKET_NOWAIT
) ||
1062 !(flags
& (wxSOCKET_WAITALL
| wxSOCKET_BLOCK
)),
1063 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1064 "wxSOCKET_NOWAIT doesn't make sense" );
1070 // --------------------------------------------------------------------------
1072 // --------------------------------------------------------------------------
1074 // A note on how events are processed, which is probably the most
1075 // difficult thing to get working right while keeping the same API
1076 // and functionality for all platforms.
1078 // When GSocket detects an event, it calls wx_socket_callback, which in
1079 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
1080 // object. OnRequest does some housekeeping, and if the event is to be
1081 // propagated to the user, it creates a new wxSocketEvent object and
1082 // posts it. The event is not processed immediately, but delayed with
1083 // AddPendingEvent instead. This is necessary in order to decouple the
1084 // event processing from wx_socket_callback; otherwise, subsequent IO
1085 // calls made from the user event handler would fail, as gtk callbacks
1086 // are not reentrant.
1088 // Note that, unlike events, user callbacks (now deprecated) are _not_
1089 // decoupled from wx_socket_callback and thus they suffer from a variety
1090 // of problems. Avoid them where possible and use events instead.
1093 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
1094 GSocketEvent notification
,
1097 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
1099 sckobj
->OnRequest((wxSocketNotify
) notification
);
1102 void wxSocketBase::OnRequest(wxSocketNotify notification
)
1104 switch(notification
)
1106 case wxSOCKET_CONNECTION
:
1107 m_establishing
= false;
1111 // If we are in the middle of a R/W operation, do not
1112 // propagate events to users. Also, filter 'late' events
1113 // which are no longer valid.
1115 case wxSOCKET_INPUT
:
1116 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
1120 case wxSOCKET_OUTPUT
:
1121 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
1126 m_connected
= false;
1127 m_establishing
= false;
1131 // Schedule the event
1133 wxSocketEventFlags flag
= 0;
1135 switch (notification
)
1137 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
1138 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
1139 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
1140 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
1142 wxLogWarning(_("wxSocket: unknown event!."));
1146 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1150 wxSocketEvent
event(m_id
);
1151 event
.m_event
= notification
;
1152 event
.m_clientData
= m_clientData
;
1153 event
.SetEventObject(this);
1155 m_handler
->AddPendingEvent(event
);
1160 void wxSocketBase::Notify(bool notify
)
1164 m_socket
->Notify(notify
);
1167 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1169 m_eventmask
= flags
;
1172 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1174 m_handler
= &handler
;
1178 // --------------------------------------------------------------------------
1180 // --------------------------------------------------------------------------
1182 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1186 if (m_unread
== NULL
)
1187 m_unread
= malloc(size
);
1192 tmp
= malloc(m_unrd_size
+ size
);
1193 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1199 m_unrd_size
+= size
;
1201 memcpy(m_unread
, buffer
, size
);
1204 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1206 wxCHECK_MSG( buffer
, 0, "NULL buffer" );
1211 if (size
> (m_unrd_size
-m_unrd_cur
))
1212 size
= m_unrd_size
-m_unrd_cur
;
1214 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1219 if (m_unrd_size
== m_unrd_cur
)
1232 // ==========================================================================
1234 // ==========================================================================
1236 // --------------------------------------------------------------------------
1238 // --------------------------------------------------------------------------
1240 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1241 wxSocketFlags flags
)
1242 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1244 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1246 m_socket
= GSocket_new();
1250 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1254 // Setup the socket as server
1255 m_socket
->Notify(m_notify
);
1256 m_socket
->SetLocal(addr_man
.GetAddress());
1258 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1259 m_socket
->SetReusable();
1261 if (GetFlags() & wxSOCKET_BROADCAST
) {
1262 m_socket
->SetBroadcast();
1264 if (GetFlags() & wxSOCKET_NOBIND
) {
1265 m_socket
->DontDoBind();
1268 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1273 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1277 m_socket
->SetTimeout(m_timeout
* 1000);
1278 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1279 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1280 wx_socket_callback
, (char *)this);
1282 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_socket
->m_fd
);
1285 // --------------------------------------------------------------------------
1287 // --------------------------------------------------------------------------
1289 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1294 // If wait == false, then the call should be nonblocking.
1295 // When we are finished, we put the socket to blocking mode
1297 wxSocketUnblocker
unblock(m_socket
, !wait
);
1298 GSocket
* const child_socket
= m_socket
->WaitConnection();
1303 sock
.m_type
= wxSOCKET_BASE
;
1304 sock
.m_socket
= child_socket
;
1305 sock
.m_connected
= true;
1307 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1308 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1309 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1310 wx_socket_callback
, (char *)&sock
);
1315 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1317 wxSocketBase
* sock
= new wxSocketBase();
1319 sock
->SetFlags(m_flags
);
1321 if (!AcceptWith(*sock
, wait
))
1330 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1332 return DoWait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1335 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1337 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1339 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1347 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1350 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1352 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1360 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1362 GAddress
* la
= local
.GetAddress();
1364 // If the address is valid, save it for use when we call Connect
1365 if (la
&& la
->m_addr
)
1367 m_localAddress
= local
;
1375 // ==========================================================================
1377 // ==========================================================================
1379 // --------------------------------------------------------------------------
1381 // --------------------------------------------------------------------------
1383 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1384 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1386 m_initialRecvBufferSize
=
1387 m_initialSendBufferSize
= -1;
1390 wxSocketClient::~wxSocketClient()
1394 // --------------------------------------------------------------------------
1396 // --------------------------------------------------------------------------
1398 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1399 const wxSockAddress
* local
,
1404 // Shutdown and destroy the socket
1409 m_socket
= GSocket_new();
1410 m_connected
= false;
1411 m_establishing
= false;
1416 m_socket
->SetTimeout(m_timeout
* 1000);
1417 m_socket
->SetCallback(
1421 GSOCK_CONNECTION_FLAG
,
1426 // If wait == false, then the call should be nonblocking. When we are
1427 // finished, we put the socket to blocking mode again.
1428 wxSocketUnblocker
unblock(m_socket
, !wait
);
1430 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1431 if (GetFlags() & wxSOCKET_REUSEADDR
)
1433 m_socket
->SetReusable();
1435 if (GetFlags() & wxSOCKET_BROADCAST
)
1437 m_socket
->SetBroadcast();
1439 if (GetFlags() & wxSOCKET_NOBIND
)
1441 m_socket
->DontDoBind();
1444 // If no local address was passed and one has been set, use the one that was Set
1445 if (!local
&& m_localAddress
.GetAddress())
1447 local
= &m_localAddress
;
1450 // Bind to the local IP address and port, when provided
1453 GAddress
* la
= local
->GetAddress();
1455 if (la
&& la
->m_addr
)
1456 m_socket
->SetLocal(la
);
1459 #if defined(__WXMSW__) || defined(__WXGTK__)
1460 m_socket
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1463 m_socket
->SetPeer(addr_man
.GetAddress());
1464 const GSocketError err
= m_socket
->Connect(GSOCK_STREAMED
);
1466 //this will register for callbacks - must be called after m_socket->m_fd was initialized
1467 m_socket
->Notify(m_notify
);
1469 if (err
!= GSOCK_NOERROR
)
1471 if (err
== GSOCK_WOULDBLOCK
)
1472 m_establishing
= true;
1481 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1483 return DoConnect(addr_man
, NULL
, wait
);
1486 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1487 const wxSockAddress
& local
,
1490 return DoConnect(addr_man
, &local
, wait
);
1493 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1497 // this happens if the initial attempt to connect succeeded without
1502 wxCHECK_MSG( m_establishing
&& m_socket
, false,
1503 "No connection establishment attempt in progress" );
1505 // we must specify GSOCK_LOST_FLAG here explicitly because we must return
1506 // true if the connection establishment process is finished, whether it is
1507 // over because we successfully connected or because we were not able to
1509 return DoWait(seconds
, milliseconds
,
1510 GSOCK_CONNECTION_FLAG
| GSOCK_LOST_FLAG
);
1513 // ==========================================================================
1515 // ==========================================================================
1517 /* NOTE: experimental stuff - might change */
1519 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1520 wxSocketFlags flags
)
1521 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1523 // Create the socket
1524 m_socket
= GSocket_new();
1528 wxFAIL_MSG( _T("datagram socket not new'd") );
1531 m_socket
->Notify(m_notify
);
1532 // Setup the socket as non connection oriented
1533 m_socket
->SetLocal(addr
.GetAddress());
1534 if (flags
& wxSOCKET_REUSEADDR
)
1536 m_socket
->SetReusable();
1538 if (GetFlags() & wxSOCKET_BROADCAST
)
1540 m_socket
->SetBroadcast();
1542 if (GetFlags() & wxSOCKET_NOBIND
)
1544 m_socket
->DontDoBind();
1546 if ( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1553 // Initialize all stuff
1554 m_connected
= false;
1555 m_establishing
= false;
1556 m_socket
->SetTimeout( m_timeout
);
1557 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1558 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1559 wx_socket_callback
, (char*)this );
1562 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1571 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1575 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1577 m_socket
->SetPeer(addr
.GetAddress());
1582 // ==========================================================================
1584 // ==========================================================================
1586 class wxSocketModule
: public wxModule
1589 virtual bool OnInit()
1591 // wxSocketBase will call GSocket_Init() itself when/if needed
1595 virtual void OnExit()
1597 if ( wxSocketBase::IsInitialized() )
1598 wxSocketBase::Shutdown();
1602 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1605 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)
1607 #endif // wxUSE_SOCKETS