1 /////////////////////////////////////////////////////////////////////////////
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: see wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ==========================================================================
14 // ==========================================================================
16 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
17 #pragma implementation "socket.h"
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
30 #include "wx/apptrait.h"
32 #include "wx/object.h"
33 #include "wx/string.h"
36 #include "wx/module.h"
41 #include "wx/sckaddr.h"
42 #include "wx/socket.h"
43 #include "wx/stopwatch.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 // what to do within waits: we have 2 cases: from the main thread itself we
57 // have to call wxYield() to let the events (including the GUI events and the
58 // low-level (not wxWidgets) events from GSocket) be processed. From another
59 // thread it is enough to just call wxThread::Yield() which will give away the
60 // rest of our time slice: the explanation is that the events will be processed
61 // by the main thread anyhow, without calling wxYield(), but we don't want to
62 // eat the CPU time uselessly while sitting in the loop waiting for the data
64 #define PROCESS_EVENTS() \
66 if ( wxThread::IsMain() ) \
71 #else // !wxUSE_THREADS
72 #define PROCESS_EVENTS() wxYield()
73 #endif // wxUSE_THREADS/!wxUSE_THREADS
75 #define wxTRACE_Socket _T("wxSocket")
77 // --------------------------------------------------------------------------
79 // --------------------------------------------------------------------------
81 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
82 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
83 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
84 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
85 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
87 // --------------------------------------------------------------------------
89 // --------------------------------------------------------------------------
91 class wxSocketState
: public wxObject
94 wxSocketFlags m_flags
;
95 wxSocketEventFlags m_eventmask
;
100 wxSocketState() : wxObject() {}
102 DECLARE_NO_COPY_CLASS(wxSocketState
)
105 // ==========================================================================
107 // ==========================================================================
109 // --------------------------------------------------------------------------
110 // Initialization and shutdown
111 // --------------------------------------------------------------------------
113 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
114 // to m_countInit with a crit section
115 size_t wxSocketBase::m_countInit
= 0;
117 bool wxSocketBase::IsInitialized()
119 return m_countInit
> 0;
122 bool wxSocketBase::Initialize()
124 if ( !m_countInit
++ )
127 Details: Initialize() creates a hidden window as a sink for socket
128 events, such as 'read completed'. wxMSW has only one message loop
129 for the main thread. If Initialize is called in a secondary thread,
130 the socket window will be created for the secondary thread, but
131 since there is no message loop on this thread, it will never
132 receive events and all socket operations will time out.
133 BTW, the main thread must not be stopped using sleep or block
134 on a semaphore (a bad idea in any case) or socket operations
137 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
138 the main thread. Because secondary threads do not have run loops,
139 adding event notifications to the "Current" loop would have no
140 effect at all, events would never fire.
142 wxASSERT_MSG( wxIsMainThread(),
143 wxT("Call wxSocketBase::Initialize() from the main thread first!"));
145 wxAppTraits
*traits
= wxAppConsole::GetInstance() ?
146 wxAppConsole::GetInstance()->GetTraits() : NULL
;
147 GSocketGUIFunctionsTable
*functions
=
148 traits
? traits
->GetSocketGUIFunctionsTable() : NULL
;
149 GSocket_SetGUIFunctions(functions
);
151 if ( !GSocket_Init() )
162 void wxSocketBase::Shutdown()
164 // we should be initialized
165 wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") );
166 if ( !--m_countInit
)
172 // --------------------------------------------------------------------------
174 // --------------------------------------------------------------------------
176 void wxSocketBase::Init()
179 m_type
= wxSOCKET_UNINIT
;
190 m_beingDeleted
= false;
204 if ( !IsInitialized() )
206 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
207 // other calls to it should be matched by a call to Shutdown()
212 wxSocketBase::wxSocketBase()
217 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
225 wxSocketBase::~wxSocketBase()
227 // Just in case the app called Destroy() *and* then deleted
228 // the socket immediately: don't leave dangling pointers.
229 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
231 traits
->RemoveFromPendingDelete(this);
233 // Shutdown and close the socket
237 // Destroy the GSocket object
241 // Free the pushback buffer
246 bool wxSocketBase::Destroy()
248 // Delayed destruction: the socket will be deleted during the next
249 // idle loop iteration. This ensures that all pending events have
251 m_beingDeleted
= true;
253 // Shutdown and close the socket
256 // Supress events from now on
259 // schedule this object for deletion
260 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
263 // let the traits object decide what to do with us
264 traits
->ScheduleForDestroy(this);
266 else // no app or no traits
268 // in wxBase we might have no app object at all, don't leak memory
275 // --------------------------------------------------------------------------
277 // --------------------------------------------------------------------------
279 // The following IO operations update m_error and m_lcount:
280 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
282 // TODO: Should Connect, Accept and AcceptWith update m_error?
284 bool wxSocketBase::Close()
286 // Interrupt pending waits
292 m_socket
->UnsetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
293 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
295 // Shutdown the connection
296 m_socket
->Shutdown();
300 m_establishing
= false;
304 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
309 m_lcount
= _Read(buffer
, nbytes
);
311 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
312 if (m_flags
& wxSOCKET_WAITALL
)
313 m_error
= (m_lcount
!= nbytes
);
315 m_error
= (m_lcount
== 0);
317 // Allow read events from now on
323 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
327 // Try the pushback buffer first
328 total
= GetPushback(buffer
, nbytes
, false);
330 buffer
= (char *)buffer
+ total
;
332 // Return now in one of the following cases:
333 // - the socket is invalid,
334 // - we got all the data,
335 // - we got *some* data and we are not using wxSOCKET_WAITALL.
338 ((total
!= 0) && !(m_flags
& wxSOCKET_WAITALL
)) )
341 // Possible combinations (they are checked in this order)
343 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
348 if (m_flags
& wxSOCKET_NOWAIT
)
350 m_socket
->SetNonBlocking(1);
351 ret
= m_socket
->Read((char *)buffer
, nbytes
);
352 m_socket
->SetNonBlocking(0);
363 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
366 ret
= m_socket
->Read((char *)buffer
, nbytes
);
372 buffer
= (char *)buffer
+ ret
;
375 // If we got here and wxSOCKET_WAITALL is not set, we can leave
376 // now. Otherwise, wait until we recv all the data or until there
379 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
386 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
388 wxUint32 len
, len2
, sig
, total
;
393 unsigned char sig
[4];
394 unsigned char len
[4];
403 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
405 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
408 sig
= (wxUint32
)msg
.sig
[0];
409 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
410 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
411 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
413 if (sig
!= 0xfeeddead)
415 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
419 len
= (wxUint32
)msg
.len
[0];
420 len
|= (wxUint32
)(msg
.len
[1] << 8);
421 len
|= (wxUint32
)(msg
.len
[2] << 16);
422 len
|= (wxUint32
)(msg
.len
[3] << 24);
432 // Don't attemp to read if the msg was zero bytes long.
435 total
= _Read(buffer
, len
);
442 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
445 // NOTE: discarded bytes don't add to m_lcount.
448 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
449 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
450 len2
-= (wxUint32
)discard_len
;
452 while ((discard_len
> 0) && len2
);
454 delete [] discard_buffer
;
459 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
462 sig
= (wxUint32
)msg
.sig
[0];
463 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
464 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
465 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
467 if (sig
!= 0xdeadfeed)
469 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
485 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
490 m_lcount
= _Read(buffer
, nbytes
);
491 Pushback(buffer
, m_lcount
);
493 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
494 if (m_flags
& wxSOCKET_WAITALL
)
495 m_error
= (m_lcount
!= nbytes
);
497 m_error
= (m_lcount
== 0);
499 // Allow read events again
505 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
510 m_lcount
= _Write(buffer
, nbytes
);
512 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
513 if (m_flags
& wxSOCKET_WAITALL
)
514 m_error
= (m_lcount
!= nbytes
);
516 m_error
= (m_lcount
== 0);
518 // Allow write events again
524 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
528 // If the socket is invalid or parameters are ill, return immediately
529 if (!m_socket
|| !buffer
|| !nbytes
)
532 // Possible combinations (they are checked in this order)
534 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
539 if (m_flags
& wxSOCKET_NOWAIT
)
541 m_socket
->SetNonBlocking(1);
542 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
543 m_socket
->SetNonBlocking(0);
554 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
557 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
563 buffer
= (const char *)buffer
+ ret
;
566 // If we got here and wxSOCKET_WAITALL is not set, we can leave
567 // now. Otherwise, wait until we send all the data or until there
570 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
577 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
583 unsigned char sig
[4];
584 unsigned char len
[4];
592 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
594 msg
.sig
[0] = (unsigned char) 0xad;
595 msg
.sig
[1] = (unsigned char) 0xde;
596 msg
.sig
[2] = (unsigned char) 0xed;
597 msg
.sig
[3] = (unsigned char) 0xfe;
599 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
600 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
601 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
602 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
604 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
607 total
= _Write(buffer
, nbytes
);
612 msg
.sig
[0] = (unsigned char) 0xed;
613 msg
.sig
[1] = (unsigned char) 0xfe;
614 msg
.sig
[2] = (unsigned char) 0xad;
615 msg
.sig
[3] = (unsigned char) 0xde;
616 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
618 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
632 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
635 Pushback(buffer
, nbytes
);
643 wxSocketBase
& wxSocketBase::Discard()
645 char *buffer
= new char[MAX_DISCARD_SIZE
];
652 SetFlags(wxSOCKET_NOWAIT
);
656 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
659 while (ret
== MAX_DISCARD_SIZE
);
665 // Allow read events again
671 // --------------------------------------------------------------------------
673 // --------------------------------------------------------------------------
675 // All Wait functions poll the socket using GSocket_Select() to
676 // check for the specified combination of conditions, until one
677 // of these conditions become true, an error occurs, or the
678 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
679 // this won't block the GUI.
681 bool wxSocketBase::_Wait(long seconds
,
683 wxSocketEventFlags flags
)
685 GSocketEventFlags result
;
688 // Set this to true to interrupt ongoing waits
691 // Check for valid socket
695 // Check for valid timeout value.
697 timeout
= seconds
* 1000 + milliseconds
;
699 timeout
= m_timeout
* 1000;
701 #if !defined(wxUSE_GUI) || !wxUSE_GUI
702 m_socket
->SetTimeout(timeout
);
705 // Wait in an active polling loop.
707 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
708 // hurt. It has to be here because the (GSocket) event might arrive
709 // a bit delayed, and it has to be in OnRequest as well because we
710 // don't know whether the Wait functions are being used.
712 // Do this at least once (important if timeout == 0, when
713 // we are just polling). Also, if just polling, do not yield.
720 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
722 // Incoming connection (server) or connection established (client)
723 if (result
& GSOCK_CONNECTION_FLAG
)
726 m_establishing
= false;
730 // Data available or output buffer ready
731 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
737 if (result
& GSOCK_LOST_FLAG
)
740 m_establishing
= false;
741 return (flags
& GSOCK_LOST_FLAG
) != 0;
745 if ((!timeout
) || (chrono
.Time() > timeout
) || (m_interrupt
))
754 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
756 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
758 GSOCK_CONNECTION_FLAG
|
762 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
764 // Check pushback buffer before entering _Wait
768 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
769 // _Wait becuase of the semantics of WaitForRead: a return
770 // value of true means that a GSocket_Read call will return
771 // immediately, not that there is actually data to read.
773 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
778 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
780 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
783 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
785 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
788 // --------------------------------------------------------------------------
790 // --------------------------------------------------------------------------
793 // Get local or peer address
796 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
803 peer
= m_socket
->GetPeer();
805 // copying a null address would just trigger an assert anyway
810 addr_man
.SetAddress(peer
);
811 GAddress_destroy(peer
);
816 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
823 local
= m_socket
->GetLocal();
824 addr_man
.SetAddress(local
);
825 GAddress_destroy(local
);
831 // Save and restore socket state
834 void wxSocketBase::SaveState()
836 wxSocketState
*state
;
838 state
= new wxSocketState();
840 state
->m_flags
= m_flags
;
841 state
->m_notify
= m_notify
;
842 state
->m_eventmask
= m_eventmask
;
843 state
->m_clientData
= m_clientData
;
845 m_states
.Append(state
);
848 void wxSocketBase::RestoreState()
850 wxList::compatibility_iterator node
;
851 wxSocketState
*state
;
853 node
= m_states
.GetLast();
857 state
= (wxSocketState
*)node
->GetData();
859 m_flags
= state
->m_flags
;
860 m_notify
= state
->m_notify
;
861 m_eventmask
= state
->m_eventmask
;
862 m_clientData
= state
->m_clientData
;
864 m_states
.Erase(node
);
872 void wxSocketBase::SetTimeout(long seconds
)
877 m_socket
->SetTimeout(m_timeout
* 1000);
880 void wxSocketBase::SetFlags(wxSocketFlags flags
)
886 // --------------------------------------------------------------------------
888 // --------------------------------------------------------------------------
890 // A note on how events are processed, which is probably the most
891 // difficult thing to get working right while keeping the same API
892 // and functionality for all platforms.
894 // When GSocket detects an event, it calls wx_socket_callback, which in
895 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
896 // object. OnRequest does some housekeeping, and if the event is to be
897 // propagated to the user, it creates a new wxSocketEvent object and
898 // posts it. The event is not processed immediately, but delayed with
899 // AddPendingEvent instead. This is necessary in order to decouple the
900 // event processing from wx_socket_callback; otherwise, subsequent IO
901 // calls made from the user event handler would fail, as gtk callbacks
902 // are not reentrant.
904 // Note that, unlike events, user callbacks (now deprecated) are _not_
905 // decoupled from wx_socket_callback and thus they suffer from a variety
906 // of problems. Avoid them where possible and use events instead.
909 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
910 GSocketEvent notification
,
913 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
915 sckobj
->OnRequest((wxSocketNotify
) notification
);
918 void wxSocketBase::OnRequest(wxSocketNotify notification
)
920 // NOTE: We duplicate some of the code in _Wait, but this doesn't
921 // hurt. It has to be here because the (GSocket) event might arrive
922 // a bit delayed, and it has to be in _Wait as well because we don't
923 // know whether the Wait functions are being used.
927 case wxSOCKET_CONNECTION
:
928 m_establishing
= false;
932 // If we are in the middle of a R/W operation, do not
933 // propagate events to users. Also, filter 'late' events
934 // which are no longer valid.
937 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
941 case wxSOCKET_OUTPUT
:
942 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
948 m_establishing
= false;
955 // Schedule the event
957 wxSocketEventFlags flag
= 0;
959 switch (notification
)
961 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
962 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
963 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
964 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
966 wxLogWarning(_("wxSocket: unknown event!."));
970 if (((m_eventmask
& flag
) == flag
) && m_notify
)
974 wxSocketEvent
event(m_id
);
975 event
.m_event
= notification
;
976 event
.m_clientData
= m_clientData
;
977 event
.SetEventObject(this);
979 m_handler
->AddPendingEvent(event
);
984 void wxSocketBase::Notify(bool notify
)
989 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
994 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
996 m_handler
= &handler
;
1000 // --------------------------------------------------------------------------
1002 // --------------------------------------------------------------------------
1004 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1008 if (m_unread
== NULL
)
1009 m_unread
= malloc(size
);
1014 tmp
= malloc(m_unrd_size
+ size
);
1015 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1021 m_unrd_size
+= size
;
1023 memcpy(m_unread
, buffer
, size
);
1026 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1031 if (size
> (m_unrd_size
-m_unrd_cur
))
1032 size
= m_unrd_size
-m_unrd_cur
;
1034 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1039 if (m_unrd_size
== m_unrd_cur
)
1052 // ==========================================================================
1054 // ==========================================================================
1056 // --------------------------------------------------------------------------
1058 // --------------------------------------------------------------------------
1060 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
1061 wxSocketFlags flags
)
1062 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1064 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1066 m_socket
= GSocket_new();
1070 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1074 // Setup the socket as server
1076 m_socket
->SetLocal(addr_man
.GetAddress());
1078 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1079 m_socket
->SetReusable();
1082 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1087 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1091 m_socket
->SetTimeout(m_timeout
* 1000);
1092 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1093 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1094 wx_socket_callback
, (char *)this);
1097 // --------------------------------------------------------------------------
1099 // --------------------------------------------------------------------------
1101 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1103 GSocket
*child_socket
;
1108 // If wait == false, then the call should be nonblocking.
1109 // When we are finished, we put the socket to blocking mode
1113 m_socket
->SetNonBlocking(1);
1115 child_socket
= m_socket
->WaitConnection();
1118 m_socket
->SetNonBlocking(0);
1123 sock
.m_type
= wxSOCKET_BASE
;
1124 sock
.m_socket
= child_socket
;
1125 sock
.m_connected
= true;
1127 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1128 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1129 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1130 wx_socket_callback
, (char *)&sock
);
1135 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1137 wxSocketBase
* sock
= new wxSocketBase();
1139 sock
->SetFlags(m_flags
);
1141 if (!AcceptWith(*sock
, wait
))
1150 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1152 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1155 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1157 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1165 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1168 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1176 // ==========================================================================
1178 // ==========================================================================
1180 // --------------------------------------------------------------------------
1182 // --------------------------------------------------------------------------
1184 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1185 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1189 wxSocketClient::~wxSocketClient()
1193 // --------------------------------------------------------------------------
1195 // --------------------------------------------------------------------------
1197 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1203 // Shutdown and destroy the socket
1208 m_socket
= GSocket_new();
1209 m_connected
= false;
1210 m_establishing
= false;
1215 m_socket
->SetTimeout(m_timeout
* 1000);
1216 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1217 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1218 wx_socket_callback
, (char *)this);
1220 // If wait == false, then the call should be nonblocking.
1221 // When we are finished, we put the socket to blocking mode
1225 m_socket
->SetNonBlocking(1);
1227 m_socket
->SetPeer(addr_man
.GetAddress());
1228 err
= m_socket
->Connect(GSOCK_STREAMED
);
1231 m_socket
->SetNonBlocking(0);
1233 if (err
!= GSOCK_NOERROR
)
1235 if (err
== GSOCK_WOULDBLOCK
)
1236 m_establishing
= true;
1245 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1247 if (m_connected
) // Already connected
1250 if (!m_establishing
|| !m_socket
) // No connection in progress
1253 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1257 // ==========================================================================
1259 // ==========================================================================
1261 /* NOTE: experimental stuff - might change */
1263 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
,
1264 wxSocketFlags flags
)
1265 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1267 // Create the socket
1268 m_socket
= GSocket_new();
1272 wxASSERT_MSG( 0, _T("datagram socket not new'd") );
1275 // Setup the socket as non connection oriented
1276 m_socket
->SetLocal(addr
.GetAddress());
1277 if( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1284 // Initialize all stuff
1285 m_connected
= false;
1286 m_establishing
= false;
1287 m_socket
->SetTimeout( m_timeout
);
1288 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1289 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1290 wx_socket_callback
, (char*)this );
1294 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1303 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1307 m_socket
->SetPeer(addr
.GetAddress());
1312 // ==========================================================================
1314 // ==========================================================================
1316 class wxSocketModule
: public wxModule
1319 virtual bool OnInit()
1321 // wxSocketBase will call GSocket_Init() itself when/if needed
1325 virtual void OnExit()
1327 if ( wxSocketBase::IsInitialized() )
1328 wxSocketBase::Shutdown();
1332 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1335 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)