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"
34 #include "wx/stopwatch.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 wxWindows) 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
;
97 #if WXWIN_COMPATIBILITY
98 wxSocketBase::wxSockCbk m_cbk
;
100 #endif // WXWIN_COMPATIBILITY
103 wxSocketState() : wxObject() {}
105 DECLARE_NO_COPY_CLASS(wxSocketState
)
108 // ==========================================================================
110 // ==========================================================================
112 // --------------------------------------------------------------------------
113 // Initialization and shutdown
114 // --------------------------------------------------------------------------
116 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
117 // to m_countInit with a crit section
118 size_t wxSocketBase::m_countInit
= 0;
120 bool wxSocketBase::IsInitialized()
122 return m_countInit
> 0;
125 bool wxSocketBase::Initialize()
127 if ( !m_countInit
++ )
129 wxAppTraits
*traits
= wxAppConsole::GetInstance() ?
130 wxAppConsole::GetInstance()->GetTraits() : NULL
;
131 GSocketGUIFunctionsTable
*functions
=
132 traits
? traits
->GetSocketGUIFunctionsTable() : NULL
;
133 GSocket_SetGUIFunctions(functions
);
135 if ( !GSocket_Init() )
146 void wxSocketBase::Shutdown()
148 // we should be initialized
149 wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") );
150 if ( !--m_countInit
)
156 // --------------------------------------------------------------------------
158 // --------------------------------------------------------------------------
160 void wxSocketBase::Init()
163 m_type
= wxSOCKET_UNINIT
;
174 m_beingDeleted
= FALSE
;
187 #if WXWIN_COMPATIBILITY
190 #endif // WXWIN_COMPATIBILITY
192 if ( !IsInitialized() )
194 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
195 // other calls to it should be matched by a call to Shutdown()
200 wxSocketBase::wxSocketBase()
205 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
213 wxSocketBase::~wxSocketBase()
215 // Just in case the app called Destroy() *and* then deleted
216 // the socket immediately: don't leave dangling pointers.
217 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
219 traits
->RemoveFromPendingDelete(this);
221 // Shutdown and close the socket
225 // Destroy the GSocket object
227 GSocket_destroy(m_socket
);
229 // Free the pushback buffer
234 bool wxSocketBase::Destroy()
236 // Delayed destruction: the socket will be deleted during the next
237 // idle loop iteration. This ensures that all pending events have
239 m_beingDeleted
= TRUE
;
241 // Shutdown and close the socket
244 // Supress events from now on
247 // schedule this object for deletion
248 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
251 // let the traits object decide what to do with us
252 traits
->ScheduleForDestroy(this);
254 else // no app or no traits
256 // in wxBase we might have no app object at all, don't leak memory
263 // --------------------------------------------------------------------------
265 // --------------------------------------------------------------------------
267 // The following IO operations update m_error and m_lcount:
268 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
270 // TODO: Should Connect, Accept and AcceptWith update m_error?
272 bool wxSocketBase::Close()
274 // Interrupt pending waits
280 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
281 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
283 // Shutdown the connection
284 GSocket_Shutdown(m_socket
);
288 m_establishing
= FALSE
;
292 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
297 m_lcount
= _Read(buffer
, nbytes
);
299 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
300 if (m_flags
& wxSOCKET_WAITALL
)
301 m_error
= (m_lcount
!= nbytes
);
303 m_error
= (m_lcount
== 0);
305 // Allow read events from now on
311 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
316 // Try the pushback buffer first
317 total
= GetPushback(buffer
, nbytes
, FALSE
);
319 buffer
= (char *)buffer
+ total
;
321 // Return now in one of the following cases:
322 // - the socket is invalid,
323 // - we got all the data,
324 // - we got *some* data and we are not using wxSOCKET_WAITALL.
327 ((total
!= 0) && !(m_flags
& wxSOCKET_WAITALL
)) )
330 // Possible combinations (they are checked in this order)
332 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
336 if (m_flags
& wxSOCKET_NOWAIT
)
338 GSocket_SetNonBlocking(m_socket
, 1);
339 ret
= GSocket_Read(m_socket
, (char *)buffer
, nbytes
);
340 GSocket_SetNonBlocking(m_socket
, 0);
351 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
354 ret
= GSocket_Read(m_socket
, (char *)buffer
, nbytes
);
360 buffer
= (char *)buffer
+ ret
;
363 // If we got here and wxSOCKET_WAITALL is not set, we can leave
364 // now. Otherwise, wait until we recv all the data or until there
367 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
374 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
376 wxUint32 len
, len2
, sig
, total
;
381 unsigned char sig
[4];
382 unsigned char len
[4];
391 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
393 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
396 sig
= (wxUint32
)msg
.sig
[0];
397 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
398 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
399 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
401 if (sig
!= 0xfeeddead)
403 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
407 len
= (wxUint32
)msg
.len
[0];
408 len
|= (wxUint32
)(msg
.len
[1] << 8);
409 len
|= (wxUint32
)(msg
.len
[2] << 16);
410 len
|= (wxUint32
)(msg
.len
[3] << 24);
420 // Don't attemp to read if the msg was zero bytes long.
423 total
= _Read(buffer
, len
);
430 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
433 // NOTE: discarded bytes don't add to m_lcount.
436 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
437 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
438 len2
-= (wxUint32
)discard_len
;
440 while ((discard_len
> 0) && len2
);
442 delete [] discard_buffer
;
447 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
450 sig
= (wxUint32
)msg
.sig
[0];
451 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
452 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
453 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
455 if (sig
!= 0xdeadfeed)
457 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
473 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
478 m_lcount
= _Read(buffer
, nbytes
);
479 Pushback(buffer
, m_lcount
);
481 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
482 if (m_flags
& wxSOCKET_WAITALL
)
483 m_error
= (m_lcount
!= nbytes
);
485 m_error
= (m_lcount
== 0);
487 // Allow read events again
493 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
498 m_lcount
= _Write(buffer
, nbytes
);
500 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
501 if (m_flags
& wxSOCKET_WAITALL
)
502 m_error
= (m_lcount
!= nbytes
);
504 m_error
= (m_lcount
== 0);
506 // Allow write events again
512 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
517 // If the socket is invalid or parameters are ill, return immediately
518 if (!m_socket
|| !buffer
|| !nbytes
)
521 // Possible combinations (they are checked in this order)
523 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
527 if (m_flags
& wxSOCKET_NOWAIT
)
529 GSocket_SetNonBlocking(m_socket
, 1);
530 ret
= GSocket_Write(m_socket
, (const char *)buffer
, nbytes
);
531 GSocket_SetNonBlocking(m_socket
, 0);
542 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
545 ret
= GSocket_Write(m_socket
, (const char *)buffer
, nbytes
);
551 buffer
= (const char *)buffer
+ ret
;
554 // If we got here and wxSOCKET_WAITALL is not set, we can leave
555 // now. Otherwise, wait until we send all the data or until there
558 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
565 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
571 unsigned char sig
[4];
572 unsigned char len
[4];
580 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
582 msg
.sig
[0] = (unsigned char) 0xad;
583 msg
.sig
[1] = (unsigned char) 0xde;
584 msg
.sig
[2] = (unsigned char) 0xed;
585 msg
.sig
[3] = (unsigned char) 0xfe;
587 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
588 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
589 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
590 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
592 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
595 total
= _Write(buffer
, nbytes
);
600 msg
.sig
[0] = (unsigned char) 0xed;
601 msg
.sig
[1] = (unsigned char) 0xfe;
602 msg
.sig
[2] = (unsigned char) 0xad;
603 msg
.sig
[3] = (unsigned char) 0xde;
604 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
606 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
620 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
623 Pushback(buffer
, nbytes
);
631 wxSocketBase
& wxSocketBase::Discard()
633 char *buffer
= new char[MAX_DISCARD_SIZE
];
640 SetFlags(wxSOCKET_NOWAIT
);
644 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
647 while (ret
== MAX_DISCARD_SIZE
);
653 // Allow read events again
659 // --------------------------------------------------------------------------
661 // --------------------------------------------------------------------------
663 // All Wait functions poll the socket using GSocket_Select() to
664 // check for the specified combination of conditions, until one
665 // of these conditions become true, an error occurs, or the
666 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
667 // this won't block the GUI.
669 bool wxSocketBase::_Wait(long seconds
,
671 wxSocketEventFlags flags
)
673 GSocketEventFlags result
;
676 // Set this to TRUE to interrupt ongoing waits
679 // Check for valid socket
683 // Check for valid timeout value.
685 timeout
= seconds
* 1000 + milliseconds
;
687 timeout
= m_timeout
* 1000;
689 // Wait in an active polling loop.
691 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
692 // hurt. It has to be here because the (GSocket) event might arrive
693 // a bit delayed, and it has to be in OnRequest as well because we
694 // don't know whether the Wait functions are being used.
696 // Do this at least once (important if timeout == 0, when
697 // we are just polling). Also, if just polling, do not yield.
704 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
706 // Incoming connection (server) or connection established (client)
707 if (result
& GSOCK_CONNECTION_FLAG
)
710 m_establishing
= FALSE
;
714 // Data available or output buffer ready
715 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
721 if (result
& GSOCK_LOST_FLAG
)
724 m_establishing
= FALSE
;
725 return (flags
& GSOCK_LOST_FLAG
) != 0;
729 if ((!timeout
) || (chrono
.Time() > timeout
) || (m_interrupt
))
738 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
740 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
742 GSOCK_CONNECTION_FLAG
|
746 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
748 // Check pushback buffer before entering _Wait
752 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
753 // _Wait becuase of the semantics of WaitForRead: a return
754 // value of TRUE means that a GSocket_Read call will return
755 // immediately, not that there is actually data to read.
757 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
761 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
763 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
766 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
768 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
771 // --------------------------------------------------------------------------
773 // --------------------------------------------------------------------------
776 // Get local or peer address
779 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
786 peer
= GSocket_GetPeer(m_socket
);
788 // copying a null address would just trigger an assert anyway
793 addr_man
.SetAddress(peer
);
794 GAddress_destroy(peer
);
799 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
806 local
= GSocket_GetLocal(m_socket
);
807 addr_man
.SetAddress(local
);
808 GAddress_destroy(local
);
814 // Save and restore socket state
817 void wxSocketBase::SaveState()
819 wxSocketState
*state
;
821 state
= new wxSocketState();
823 state
->m_flags
= m_flags
;
824 state
->m_notify
= m_notify
;
825 state
->m_eventmask
= m_eventmask
;
826 state
->m_clientData
= m_clientData
;
827 #if WXWIN_COMPATIBILITY
828 state
->m_cbk
= m_cbk
;
829 state
->m_cdata
= m_cdata
;
830 #endif // WXWIN_COMPATIBILITY
832 m_states
.Append(state
);
835 void wxSocketBase::RestoreState()
837 wxList::compatibility_iterator node
;
838 wxSocketState
*state
;
840 node
= m_states
.GetLast();
844 state
= (wxSocketState
*)node
->GetData();
846 m_flags
= state
->m_flags
;
847 m_notify
= state
->m_notify
;
848 m_eventmask
= state
->m_eventmask
;
849 m_clientData
= state
->m_clientData
;
850 #if WXWIN_COMPATIBILITY
851 m_cbk
= state
->m_cbk
;
852 m_cdata
= state
->m_cdata
;
853 #endif // WXWIN_COMPATIBILITY
855 m_states
.Erase(node
);
863 void wxSocketBase::SetTimeout(long seconds
)
868 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
871 void wxSocketBase::SetFlags(wxSocketFlags flags
)
877 // --------------------------------------------------------------------------
878 // Callbacks (now obsolete - use events instead)
879 // --------------------------------------------------------------------------
881 #if WXWIN_COMPATIBILITY
883 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
885 wxSockCbk old_cbk
= cbk_
;
891 char *wxSocketBase::CallbackData(char *data
)
893 char *old_data
= m_cdata
;
899 #endif // WXWIN_COMPATIBILITY
901 // --------------------------------------------------------------------------
903 // --------------------------------------------------------------------------
905 // A note on how events are processed, which is probably the most
906 // difficult thing to get working right while keeping the same API
907 // and functionality for all platforms.
909 // When GSocket detects an event, it calls wx_socket_callback, which in
910 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
911 // object. OnRequest does some housekeeping, and if the event is to be
912 // propagated to the user, it creates a new wxSocketEvent object and
913 // posts it. The event is not processed immediately, but delayed with
914 // AddPendingEvent instead. This is necessary in order to decouple the
915 // event processing from wx_socket_callback; otherwise, subsequent IO
916 // calls made from the user event handler would fail, as gtk callbacks
917 // are not reentrant.
919 // Note that, unlike events, user callbacks (now deprecated) are _not_
920 // decoupled from wx_socket_callback and thus they suffer from a variety
921 // of problems. Avoid them where possible and use events instead.
924 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
925 GSocketEvent notification
,
928 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
930 sckobj
->OnRequest((wxSocketNotify
) notification
);
933 void wxSocketBase::OnRequest(wxSocketNotify notification
)
935 // NOTE: We duplicate some of the code in _Wait, but this doesn't
936 // hurt. It has to be here because the (GSocket) event might arrive
937 // a bit delayed, and it has to be in _Wait as well because we don't
938 // know whether the Wait functions are being used.
942 case wxSOCKET_CONNECTION
:
943 m_establishing
= FALSE
;
947 // If we are in the middle of a R/W operation, do not
948 // propagate events to users. Also, filter 'late' events
949 // which are no longer valid.
952 if (m_reading
|| !GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
956 case wxSOCKET_OUTPUT
:
957 if (m_writing
|| !GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
))
963 m_establishing
= FALSE
;
970 // Schedule the event
972 wxSocketEventFlags flag
= 0;
973 switch (notification
)
975 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
976 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
977 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
978 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
980 wxLogWarning(_("wxSocket: unknown event!."));
984 if (((m_eventmask
& flag
) == flag
) && m_notify
)
988 wxSocketEvent
event(m_id
);
989 event
.m_event
= notification
;
990 event
.m_clientData
= m_clientData
;
991 event
.SetEventObject(this);
993 m_handler
->AddPendingEvent(event
);
996 #if WXWIN_COMPATIBILITY
998 m_cbk(*this, notification
, m_cdata
);
999 #endif // WXWIN_COMPATIBILITY
1003 void wxSocketBase::Notify(bool notify
)
1008 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1010 m_eventmask
= flags
;
1013 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1015 m_handler
= &handler
;
1019 // --------------------------------------------------------------------------
1021 // --------------------------------------------------------------------------
1023 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1027 if (m_unread
== NULL
)
1028 m_unread
= malloc(size
);
1033 tmp
= malloc(m_unrd_size
+ size
);
1034 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1040 m_unrd_size
+= size
;
1042 memcpy(m_unread
, buffer
, size
);
1045 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1050 if (size
> (m_unrd_size
-m_unrd_cur
))
1051 size
= m_unrd_size
-m_unrd_cur
;
1053 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1058 if (m_unrd_size
== m_unrd_cur
)
1071 // ==========================================================================
1073 // ==========================================================================
1075 // --------------------------------------------------------------------------
1077 // --------------------------------------------------------------------------
1079 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
1080 wxSocketFlags flags
)
1081 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1083 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1085 m_socket
= GSocket_new();
1089 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1093 // Setup the socket as server
1095 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
1096 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
1098 GSocket_destroy(m_socket
);
1101 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1105 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1106 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1107 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1108 wx_socket_callback
, (char *)this);
1111 // --------------------------------------------------------------------------
1113 // --------------------------------------------------------------------------
1115 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1117 GSocket
*child_socket
;
1122 // If wait == FALSE, then the call should be nonblocking.
1123 // When we are finished, we put the socket to blocking mode
1127 GSocket_SetNonBlocking(m_socket
, 1);
1129 child_socket
= GSocket_WaitConnection(m_socket
);
1132 GSocket_SetNonBlocking(m_socket
, 0);
1137 sock
.m_type
= wxSOCKET_BASE
;
1138 sock
.m_socket
= child_socket
;
1139 sock
.m_connected
= TRUE
;
1141 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
* 1000);
1142 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1143 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1144 wx_socket_callback
, (char *)&sock
);
1149 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1151 wxSocketBase
* sock
= new wxSocketBase();
1153 sock
->SetFlags(m_flags
);
1155 if (!AcceptWith(*sock
, wait
))
1164 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1166 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1169 // ==========================================================================
1171 // ==========================================================================
1173 // --------------------------------------------------------------------------
1175 // --------------------------------------------------------------------------
1177 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1178 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1182 wxSocketClient::~wxSocketClient()
1186 // --------------------------------------------------------------------------
1188 // --------------------------------------------------------------------------
1190 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1196 // Shutdown and destroy the socket
1198 GSocket_destroy(m_socket
);
1201 m_socket
= GSocket_new();
1202 m_connected
= FALSE
;
1203 m_establishing
= FALSE
;
1208 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1209 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1210 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1211 wx_socket_callback
, (char *)this);
1213 // If wait == FALSE, then the call should be nonblocking.
1214 // When we are finished, we put the socket to blocking mode
1218 GSocket_SetNonBlocking(m_socket
, 1);
1220 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1221 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1224 GSocket_SetNonBlocking(m_socket
, 0);
1226 if (err
!= GSOCK_NOERROR
)
1228 if (err
== GSOCK_WOULDBLOCK
)
1229 m_establishing
= TRUE
;
1238 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1240 if (m_connected
) // Already connected
1243 if (!m_establishing
|| !m_socket
) // No connection in progress
1246 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1250 // ==========================================================================
1252 // ==========================================================================
1254 /* NOTE: experimental stuff - might change */
1256 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
,
1257 wxSocketFlags flags
)
1258 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1260 // Create the socket
1261 m_socket
= GSocket_new();
1266 // Setup the socket as non connection oriented
1267 GSocket_SetLocal(m_socket
, addr
.GetAddress());
1268 if( GSocket_SetNonOriented(m_socket
) != GSOCK_NOERROR
)
1270 GSocket_destroy(m_socket
);
1275 // Initialize all stuff
1276 m_connected
= FALSE
;
1277 m_establishing
= FALSE
;
1278 GSocket_SetTimeout( m_socket
, m_timeout
);
1279 GSocket_SetCallback( m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1280 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1281 wx_socket_callback
, (char*)this );
1285 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1294 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1298 GSocket_SetPeer(m_socket
, addr
.GetAddress());
1303 // ==========================================================================
1305 // ==========================================================================
1307 class wxSocketModule
: public wxModule
1310 virtual bool OnInit()
1312 // wxSocketBase will call GSocket_Init() itself when/if needed
1316 virtual void OnExit()
1318 if ( wxSocketBase::IsInitialized() )
1319 wxSocketBase::Shutdown();
1323 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1326 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)