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"
44 // DLL options compatibility check:
46 WX_CHECK_BUILD_OPTIONS("wxNet")
48 // --------------------------------------------------------------------------
49 // macros and constants
50 // --------------------------------------------------------------------------
53 #define MAX_DISCARD_SIZE (10 * 1024)
55 // what to do within waits: we have 2 cases: from the main thread itself we
56 // have to call wxYield() to let the events (including the GUI events and the
57 // low-level (not wxWidgets) events from GSocket) be processed. From another
58 // thread it is enough to just call wxThread::Yield() which will give away the
59 // rest of our time slice: the explanation is that the events will be processed
60 // by the main thread anyhow, without calling wxYield(), but we don't want to
61 // eat the CPU time uselessly while sitting in the loop waiting for the data
63 #define PROCESS_EVENTS() \
65 if ( wxThread::IsMain() ) \
70 #else // !wxUSE_THREADS
71 #define PROCESS_EVENTS() wxYield()
72 #endif // wxUSE_THREADS/!wxUSE_THREADS
74 #define wxTRACE_Socket _T("wxSocket")
76 // --------------------------------------------------------------------------
78 // --------------------------------------------------------------------------
80 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
81 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
82 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
83 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
84 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
86 // --------------------------------------------------------------------------
88 // --------------------------------------------------------------------------
90 class wxSocketState
: public wxObject
93 wxSocketFlags m_flags
;
94 wxSocketEventFlags m_eventmask
;
99 wxSocketState() : wxObject() {}
101 DECLARE_NO_COPY_CLASS(wxSocketState
)
104 // ==========================================================================
106 // ==========================================================================
108 // --------------------------------------------------------------------------
109 // Initialization and shutdown
110 // --------------------------------------------------------------------------
112 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
113 // to m_countInit with a crit section
114 size_t wxSocketBase::m_countInit
= 0;
116 bool wxSocketBase::IsInitialized()
118 return m_countInit
> 0;
121 bool wxSocketBase::Initialize()
123 if ( !m_countInit
++ )
126 Details: Initialize() creates a hidden window as a sink for socket
127 events, such as 'read completed'. wxMSW has only one message loop
128 for the main thread. If Initialize is called in a secondary thread,
129 the socket window will be created for the secondary thread, but
130 since there is no message loop on this thread, it will never
131 receive events and all socket operations will time out.
132 BTW, the main thread must not be stopped using sleep or block
133 on a semaphore (a bad idea in any case) or socket operations
136 wxASSERT_MSG( wxIsMainThread(),
137 wxT("Call wxSocketBase::Initialize() from the main thread first!"));
139 wxAppTraits
*traits
= wxAppConsole::GetInstance() ?
140 wxAppConsole::GetInstance()->GetTraits() : NULL
;
141 GSocketGUIFunctionsTable
*functions
=
142 traits
? traits
->GetSocketGUIFunctionsTable() : NULL
;
143 GSocket_SetGUIFunctions(functions
);
145 if ( !GSocket_Init() )
156 void wxSocketBase::Shutdown()
158 // we should be initialized
159 wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") );
160 if ( !--m_countInit
)
166 // --------------------------------------------------------------------------
168 // --------------------------------------------------------------------------
170 void wxSocketBase::Init()
173 m_type
= wxSOCKET_UNINIT
;
184 m_beingDeleted
= false;
198 if ( !IsInitialized() )
200 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
201 // other calls to it should be matched by a call to Shutdown()
206 wxSocketBase::wxSocketBase()
211 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
219 wxSocketBase::~wxSocketBase()
221 // Just in case the app called Destroy() *and* then deleted
222 // the socket immediately: don't leave dangling pointers.
223 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
225 traits
->RemoveFromPendingDelete(this);
227 // Shutdown and close the socket
231 // Destroy the GSocket object
235 // Free the pushback buffer
240 bool wxSocketBase::Destroy()
242 // Delayed destruction: the socket will be deleted during the next
243 // idle loop iteration. This ensures that all pending events have
245 m_beingDeleted
= true;
247 // Shutdown and close the socket
250 // Supress events from now on
253 // schedule this object for deletion
254 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
257 // let the traits object decide what to do with us
258 traits
->ScheduleForDestroy(this);
260 else // no app or no traits
262 // in wxBase we might have no app object at all, don't leak memory
269 // --------------------------------------------------------------------------
271 // --------------------------------------------------------------------------
273 // The following IO operations update m_error and m_lcount:
274 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
276 // TODO: Should Connect, Accept and AcceptWith update m_error?
278 bool wxSocketBase::Close()
280 // Interrupt pending waits
286 m_socket
->UnsetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
287 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
289 // Shutdown the connection
290 m_socket
->Shutdown();
294 m_establishing
= false;
298 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
303 m_lcount
= _Read(buffer
, nbytes
);
305 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
306 if (m_flags
& wxSOCKET_WAITALL
)
307 m_error
= (m_lcount
!= nbytes
);
309 m_error
= (m_lcount
== 0);
311 // Allow read events from now on
317 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
321 // Try the pushback buffer first
322 total
= GetPushback(buffer
, nbytes
, false);
324 buffer
= (char *)buffer
+ total
;
326 // Return now in one of the following cases:
327 // - the socket is invalid,
328 // - we got all the data,
329 // - we got *some* data and we are not using wxSOCKET_WAITALL.
332 ((total
!= 0) && !(m_flags
& wxSOCKET_WAITALL
)) )
335 // Possible combinations (they are checked in this order)
337 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
342 if (m_flags
& wxSOCKET_NOWAIT
)
344 m_socket
->SetNonBlocking(1);
345 ret
= m_socket
->Read((char *)buffer
, nbytes
);
346 m_socket
->SetNonBlocking(0);
357 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
360 ret
= m_socket
->Read((char *)buffer
, nbytes
);
366 buffer
= (char *)buffer
+ ret
;
369 // If we got here and wxSOCKET_WAITALL is not set, we can leave
370 // now. Otherwise, wait until we recv all the data or until there
373 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
380 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
382 wxUint32 len
, len2
, sig
, total
;
387 unsigned char sig
[4];
388 unsigned char len
[4];
397 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
399 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
402 sig
= (wxUint32
)msg
.sig
[0];
403 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
404 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
405 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
407 if (sig
!= 0xfeeddead)
409 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
413 len
= (wxUint32
)msg
.len
[0];
414 len
|= (wxUint32
)(msg
.len
[1] << 8);
415 len
|= (wxUint32
)(msg
.len
[2] << 16);
416 len
|= (wxUint32
)(msg
.len
[3] << 24);
426 // Don't attemp to read if the msg was zero bytes long.
429 total
= _Read(buffer
, len
);
436 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
439 // NOTE: discarded bytes don't add to m_lcount.
442 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
443 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
444 len2
-= (wxUint32
)discard_len
;
446 while ((discard_len
> 0) && len2
);
448 delete [] discard_buffer
;
453 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
456 sig
= (wxUint32
)msg
.sig
[0];
457 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
458 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
459 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
461 if (sig
!= 0xdeadfeed)
463 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
479 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
484 m_lcount
= _Read(buffer
, nbytes
);
485 Pushback(buffer
, m_lcount
);
487 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
488 if (m_flags
& wxSOCKET_WAITALL
)
489 m_error
= (m_lcount
!= nbytes
);
491 m_error
= (m_lcount
== 0);
493 // Allow read events again
499 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
504 m_lcount
= _Write(buffer
, nbytes
);
506 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
507 if (m_flags
& wxSOCKET_WAITALL
)
508 m_error
= (m_lcount
!= nbytes
);
510 m_error
= (m_lcount
== 0);
512 // Allow write events again
518 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
522 // If the socket is invalid or parameters are ill, return immediately
523 if (!m_socket
|| !buffer
|| !nbytes
)
526 // Possible combinations (they are checked in this order)
528 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
533 if (m_flags
& wxSOCKET_NOWAIT
)
535 m_socket
->SetNonBlocking(1);
536 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
537 m_socket
->SetNonBlocking(0);
548 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
551 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
557 buffer
= (const char *)buffer
+ ret
;
560 // If we got here and wxSOCKET_WAITALL is not set, we can leave
561 // now. Otherwise, wait until we send all the data or until there
564 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
571 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
577 unsigned char sig
[4];
578 unsigned char len
[4];
586 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
588 msg
.sig
[0] = (unsigned char) 0xad;
589 msg
.sig
[1] = (unsigned char) 0xde;
590 msg
.sig
[2] = (unsigned char) 0xed;
591 msg
.sig
[3] = (unsigned char) 0xfe;
593 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
594 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
595 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
596 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
598 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
601 total
= _Write(buffer
, nbytes
);
606 msg
.sig
[0] = (unsigned char) 0xed;
607 msg
.sig
[1] = (unsigned char) 0xfe;
608 msg
.sig
[2] = (unsigned char) 0xad;
609 msg
.sig
[3] = (unsigned char) 0xde;
610 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
612 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
626 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
629 Pushback(buffer
, nbytes
);
637 wxSocketBase
& wxSocketBase::Discard()
639 char *buffer
= new char[MAX_DISCARD_SIZE
];
646 SetFlags(wxSOCKET_NOWAIT
);
650 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
653 while (ret
== MAX_DISCARD_SIZE
);
659 // Allow read events again
665 // --------------------------------------------------------------------------
667 // --------------------------------------------------------------------------
669 // All Wait functions poll the socket using GSocket_Select() to
670 // check for the specified combination of conditions, until one
671 // of these conditions become true, an error occurs, or the
672 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
673 // this won't block the GUI.
675 bool wxSocketBase::_Wait(long seconds
,
677 wxSocketEventFlags flags
)
679 GSocketEventFlags result
;
682 // Set this to true to interrupt ongoing waits
685 // Check for valid socket
689 // Check for valid timeout value.
691 timeout
= seconds
* 1000 + milliseconds
;
693 timeout
= m_timeout
* 1000;
695 #if !defined(wxUSE_GUI) || !wxUSE_GUI
696 m_socket
->SetTimeout(timeout
);
699 // Wait in an active polling loop.
701 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
702 // hurt. It has to be here because the (GSocket) event might arrive
703 // a bit delayed, and it has to be in OnRequest as well because we
704 // don't know whether the Wait functions are being used.
706 // Do this at least once (important if timeout == 0, when
707 // we are just polling). Also, if just polling, do not yield.
714 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
716 // Incoming connection (server) or connection established (client)
717 if (result
& GSOCK_CONNECTION_FLAG
)
720 m_establishing
= false;
724 // Data available or output buffer ready
725 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
731 if (result
& GSOCK_LOST_FLAG
)
734 m_establishing
= false;
735 return (flags
& GSOCK_LOST_FLAG
) != 0;
739 if ((!timeout
) || (chrono
.Time() > timeout
) || (m_interrupt
))
748 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
750 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
752 GSOCK_CONNECTION_FLAG
|
756 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
758 // Check pushback buffer before entering _Wait
762 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
763 // _Wait becuase of the semantics of WaitForRead: a return
764 // value of true means that a GSocket_Read call will return
765 // immediately, not that there is actually data to read.
767 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
772 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
774 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
777 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
779 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
782 // --------------------------------------------------------------------------
784 // --------------------------------------------------------------------------
787 // Get local or peer address
790 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
797 peer
= m_socket
->GetPeer();
799 // copying a null address would just trigger an assert anyway
804 addr_man
.SetAddress(peer
);
805 GAddress_destroy(peer
);
810 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
817 local
= m_socket
->GetLocal();
818 addr_man
.SetAddress(local
);
819 GAddress_destroy(local
);
825 // Save and restore socket state
828 void wxSocketBase::SaveState()
830 wxSocketState
*state
;
832 state
= new wxSocketState();
834 state
->m_flags
= m_flags
;
835 state
->m_notify
= m_notify
;
836 state
->m_eventmask
= m_eventmask
;
837 state
->m_clientData
= m_clientData
;
839 m_states
.Append(state
);
842 void wxSocketBase::RestoreState()
844 wxList::compatibility_iterator node
;
845 wxSocketState
*state
;
847 node
= m_states
.GetLast();
851 state
= (wxSocketState
*)node
->GetData();
853 m_flags
= state
->m_flags
;
854 m_notify
= state
->m_notify
;
855 m_eventmask
= state
->m_eventmask
;
856 m_clientData
= state
->m_clientData
;
858 m_states
.Erase(node
);
866 void wxSocketBase::SetTimeout(long seconds
)
871 m_socket
->SetTimeout(m_timeout
* 1000);
874 void wxSocketBase::SetFlags(wxSocketFlags flags
)
880 // --------------------------------------------------------------------------
882 // --------------------------------------------------------------------------
884 // A note on how events are processed, which is probably the most
885 // difficult thing to get working right while keeping the same API
886 // and functionality for all platforms.
888 // When GSocket detects an event, it calls wx_socket_callback, which in
889 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
890 // object. OnRequest does some housekeeping, and if the event is to be
891 // propagated to the user, it creates a new wxSocketEvent object and
892 // posts it. The event is not processed immediately, but delayed with
893 // AddPendingEvent instead. This is necessary in order to decouple the
894 // event processing from wx_socket_callback; otherwise, subsequent IO
895 // calls made from the user event handler would fail, as gtk callbacks
896 // are not reentrant.
898 // Note that, unlike events, user callbacks (now deprecated) are _not_
899 // decoupled from wx_socket_callback and thus they suffer from a variety
900 // of problems. Avoid them where possible and use events instead.
903 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
904 GSocketEvent notification
,
907 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
909 sckobj
->OnRequest((wxSocketNotify
) notification
);
912 void wxSocketBase::OnRequest(wxSocketNotify notification
)
914 // NOTE: We duplicate some of the code in _Wait, but this doesn't
915 // hurt. It has to be here because the (GSocket) event might arrive
916 // a bit delayed, and it has to be in _Wait as well because we don't
917 // know whether the Wait functions are being used.
921 case wxSOCKET_CONNECTION
:
922 m_establishing
= false;
926 // If we are in the middle of a R/W operation, do not
927 // propagate events to users. Also, filter 'late' events
928 // which are no longer valid.
931 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
935 case wxSOCKET_OUTPUT
:
936 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
942 m_establishing
= false;
949 // Schedule the event
951 wxSocketEventFlags flag
= 0;
953 switch (notification
)
955 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
956 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
957 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
958 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
960 wxLogWarning(_("wxSocket: unknown event!."));
964 if (((m_eventmask
& flag
) == flag
) && m_notify
)
968 wxSocketEvent
event(m_id
);
969 event
.m_event
= notification
;
970 event
.m_clientData
= m_clientData
;
971 event
.SetEventObject(this);
973 m_handler
->AddPendingEvent(event
);
978 void wxSocketBase::Notify(bool notify
)
983 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
988 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
990 m_handler
= &handler
;
994 // --------------------------------------------------------------------------
996 // --------------------------------------------------------------------------
998 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1002 if (m_unread
== NULL
)
1003 m_unread
= malloc(size
);
1008 tmp
= malloc(m_unrd_size
+ size
);
1009 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1015 m_unrd_size
+= size
;
1017 memcpy(m_unread
, buffer
, size
);
1020 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1025 if (size
> (m_unrd_size
-m_unrd_cur
))
1026 size
= m_unrd_size
-m_unrd_cur
;
1028 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1033 if (m_unrd_size
== m_unrd_cur
)
1046 // ==========================================================================
1048 // ==========================================================================
1050 // --------------------------------------------------------------------------
1052 // --------------------------------------------------------------------------
1054 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
1055 wxSocketFlags flags
)
1056 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1058 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1060 m_socket
= GSocket_new();
1064 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1068 // Setup the socket as server
1070 m_socket
->SetLocal(addr_man
.GetAddress());
1072 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1073 m_socket
->SetReusable();
1076 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1081 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1085 m_socket
->SetTimeout(m_timeout
* 1000);
1086 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1087 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1088 wx_socket_callback
, (char *)this);
1091 // --------------------------------------------------------------------------
1093 // --------------------------------------------------------------------------
1095 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1097 GSocket
*child_socket
;
1102 // If wait == false, then the call should be nonblocking.
1103 // When we are finished, we put the socket to blocking mode
1107 m_socket
->SetNonBlocking(1);
1109 child_socket
= m_socket
->WaitConnection();
1112 m_socket
->SetNonBlocking(0);
1117 sock
.m_type
= wxSOCKET_BASE
;
1118 sock
.m_socket
= child_socket
;
1119 sock
.m_connected
= true;
1121 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1122 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1123 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1124 wx_socket_callback
, (char *)&sock
);
1129 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1131 wxSocketBase
* sock
= new wxSocketBase();
1133 sock
->SetFlags(m_flags
);
1135 if (!AcceptWith(*sock
, wait
))
1144 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1146 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1149 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1151 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1159 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1162 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1170 // ==========================================================================
1172 // ==========================================================================
1174 // --------------------------------------------------------------------------
1176 // --------------------------------------------------------------------------
1178 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1179 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1183 wxSocketClient::~wxSocketClient()
1187 // --------------------------------------------------------------------------
1189 // --------------------------------------------------------------------------
1191 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1197 // Shutdown and destroy the socket
1202 m_socket
= GSocket_new();
1203 m_connected
= false;
1204 m_establishing
= false;
1209 m_socket
->SetTimeout(m_timeout
* 1000);
1210 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1211 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1212 wx_socket_callback
, (char *)this);
1214 // If wait == false, then the call should be nonblocking.
1215 // When we are finished, we put the socket to blocking mode
1219 m_socket
->SetNonBlocking(1);
1221 m_socket
->SetPeer(addr_man
.GetAddress());
1222 err
= m_socket
->Connect(GSOCK_STREAMED
);
1225 m_socket
->SetNonBlocking(0);
1227 if (err
!= GSOCK_NOERROR
)
1229 if (err
== GSOCK_WOULDBLOCK
)
1230 m_establishing
= true;
1239 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1241 if (m_connected
) // Already connected
1244 if (!m_establishing
|| !m_socket
) // No connection in progress
1247 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1251 // ==========================================================================
1253 // ==========================================================================
1255 /* NOTE: experimental stuff - might change */
1257 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
,
1258 wxSocketFlags flags
)
1259 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1261 // Create the socket
1262 m_socket
= GSocket_new();
1266 wxASSERT_MSG( 0, _T("datagram socket not new'd") );
1269 // Setup the socket as non connection oriented
1270 m_socket
->SetLocal(addr
.GetAddress());
1271 if( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1278 // Initialize all stuff
1279 m_connected
= false;
1280 m_establishing
= false;
1281 m_socket
->SetTimeout( m_timeout
);
1282 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1283 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1284 wx_socket_callback
, (char*)this );
1288 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1297 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1301 m_socket
->SetPeer(addr
.GetAddress());
1306 // ==========================================================================
1308 // ==========================================================================
1310 class wxSocketModule
: public wxModule
1313 virtual bool OnInit()
1315 // wxSocketBase will call GSocket_Init() itself when/if needed
1319 virtual void OnExit()
1321 if ( wxSocketBase::IsInitialized() )
1322 wxSocketBase::Shutdown();
1326 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1329 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)