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
++ )
127 The following asserting might be neccessary for linux as well,
128 but I cannot verify this.
130 wxASSERT(wxThread::IsMain(),
131 wxT("To use sockets in a secondary thread, ")
132 wxT("call wxSocketBase::Initialize() from the main thread."));
134 Details: Initialize() creates a hidden window as a sink for socket
135 events, such as 'read completed'. wxMSW has only one message loop
136 for the main thread. If Initialize is called in a secondary thread,
137 the socket window will be created for the secondary thread, but
138 since there is no message loop on this thread, it will never
139 receive events and all socket operations will time out.
140 BTW, the main thread must not be stopped using sleep or block
141 on a semaphore (a bad idea in any case) or socket operations
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
239 GSocket_destroy(m_socket
);
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 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
293 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
295 // Shutdown the connection
296 GSocket_Shutdown(m_socket
);
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 GSocket_SetNonBlocking(m_socket
, 1);
351 ret
= GSocket_Read(m_socket
, (char *)buffer
, nbytes
);
352 GSocket_SetNonBlocking(m_socket
, 0);
363 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
366 ret
= GSocket_Read(m_socket
, (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 GSocket_SetNonBlocking(m_socket
, 1);
542 ret
= GSocket_Write(m_socket
, (const char *)buffer
, nbytes
);
543 GSocket_SetNonBlocking(m_socket
, 0);
554 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
557 ret
= GSocket_Write(m_socket
, (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 GSocket_SetTimeout(m_socket
, 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
= GSocket_Select(m_socket
, 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
= GSocket_GetPeer(m_socket
);
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
= GSocket_GetLocal(m_socket
);
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 GSocket_SetTimeout(m_socket
, 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
|| !GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
941 case wxSOCKET_OUTPUT
:
942 if (m_writing
|| !GSocket_Select(m_socket
, 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 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
1077 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
1079 GSocket_destroy(m_socket
);
1082 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1086 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1087 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1088 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1089 wx_socket_callback
, (char *)this);
1092 // --------------------------------------------------------------------------
1094 // --------------------------------------------------------------------------
1096 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1098 GSocket
*child_socket
;
1103 // If wait == FALSE, then the call should be nonblocking.
1104 // When we are finished, we put the socket to blocking mode
1108 GSocket_SetNonBlocking(m_socket
, 1);
1110 child_socket
= GSocket_WaitConnection(m_socket
);
1113 GSocket_SetNonBlocking(m_socket
, 0);
1118 sock
.m_type
= wxSOCKET_BASE
;
1119 sock
.m_socket
= child_socket
;
1120 sock
.m_connected
= TRUE
;
1122 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
* 1000);
1123 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1124 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1125 wx_socket_callback
, (char *)&sock
);
1130 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1132 wxSocketBase
* sock
= new wxSocketBase();
1134 sock
->SetFlags(m_flags
);
1136 if (!AcceptWith(*sock
, wait
))
1145 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1147 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1150 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1152 if (GSocket_GetSockOpt(m_socket
, level
, optname
, optval
, optlen
)
1160 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1163 if (GSocket_SetSockOpt(m_socket
, level
, optname
, optval
, optlen
)
1171 // ==========================================================================
1173 // ==========================================================================
1175 // --------------------------------------------------------------------------
1177 // --------------------------------------------------------------------------
1179 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1180 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1184 wxSocketClient::~wxSocketClient()
1188 // --------------------------------------------------------------------------
1190 // --------------------------------------------------------------------------
1192 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1198 // Shutdown and destroy the socket
1200 GSocket_destroy(m_socket
);
1203 m_socket
= GSocket_new();
1204 m_connected
= FALSE
;
1205 m_establishing
= FALSE
;
1210 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1211 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1212 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1213 wx_socket_callback
, (char *)this);
1215 // If wait == FALSE, then the call should be nonblocking.
1216 // When we are finished, we put the socket to blocking mode
1220 GSocket_SetNonBlocking(m_socket
, 1);
1222 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1223 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1226 GSocket_SetNonBlocking(m_socket
, 0);
1228 if (err
!= GSOCK_NOERROR
)
1230 if (err
== GSOCK_WOULDBLOCK
)
1231 m_establishing
= TRUE
;
1240 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1242 if (m_connected
) // Already connected
1245 if (!m_establishing
|| !m_socket
) // No connection in progress
1248 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1252 // ==========================================================================
1254 // ==========================================================================
1256 /* NOTE: experimental stuff - might change */
1258 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
,
1259 wxSocketFlags flags
)
1260 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1262 // Create the socket
1263 m_socket
= GSocket_new();
1267 wxASSERT_MSG( 0, _T("datagram socket not new'd") );
1270 // Setup the socket as non connection oriented
1271 GSocket_Unstreamed(m_socket
);
1272 GSocket_SetLocal(m_socket
, addr
.GetAddress());
1273 if( GSocket_SetNonOriented(m_socket
) != GSOCK_NOERROR
)
1275 GSocket_destroy(m_socket
);
1280 // Initialize all stuff
1281 m_connected
= FALSE
;
1282 m_establishing
= FALSE
;
1283 GSocket_SetTimeout( m_socket
, m_timeout
);
1284 GSocket_SetCallback( m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1285 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1286 wx_socket_callback
, (char*)this );
1290 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1299 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1303 GSocket_SetPeer(m_socket
, addr
.GetAddress());
1308 // ==========================================================================
1310 // ==========================================================================
1312 class wxSocketModule
: public wxModule
1315 virtual bool OnInit()
1317 // wxSocketBase will call GSocket_Init() itself when/if needed
1321 virtual void OnExit()
1323 if ( wxSocketBase::IsInitialized() )
1324 wxSocketBase::Shutdown();
1328 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1331 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)