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 // ==========================================================================
17 #pragma implementation "socket.h"
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
31 #include "wx/object.h"
32 #include "wx/string.h"
35 #include "wx/module.h"
41 #include "wx/gdicmn.h" // for wxPendingDelete
44 #include "wx/sckaddr.h"
45 #include "wx/socket.h"
47 // --------------------------------------------------------------------------
48 // macros and constants
49 // --------------------------------------------------------------------------
52 #define MAX_DISCARD_SIZE (10 * 1024)
54 // what to do within waits: in wxBase we don't do anything as we don't have
55 // the event loop anyhow (for now). In GUI apps we have 2 cases: from the main
56 // thread itself we have to call wxYield() to let the events (including the
57 // GUI events and the low-level (not wxWindows) events from GSocket) be
58 // processed. From another thread it is enough to just call wxThread::Yield()
59 // which will give away the rest of our time slice: the explanation is that
60 // the events will be processed by the main thread anyhow, without calling
61 // wxYield(), but we don't want to eat the CPU time uselessly while sitting
62 // in the loop waiting for the data
65 #define PROCESS_EVENTS() \
67 if ( wxThread::IsMain() ) \
72 #else // !wxUSE_THREADS
73 #define PROCESS_EVENTS() wxYield()
74 #endif // wxUSE_THREADS/!wxUSE_THREADS
76 #define PROCESS_EVENTS()
77 #endif // wxUSE_GUI/!wxUSE_GUI
79 #define wxTRACE_Socket _T("wxSocket")
81 // --------------------------------------------------------------------------
83 // --------------------------------------------------------------------------
85 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
86 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
87 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
88 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
89 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
91 // --------------------------------------------------------------------------
93 // --------------------------------------------------------------------------
95 class wxSocketState
: public wxObject
98 wxSocketFlags m_flags
;
99 wxSocketEventFlags m_eventmask
;
102 #if WXWIN_COMPATIBILITY
103 wxSocketBase::wxSockCbk m_cbk
;
105 #endif // WXWIN_COMPATIBILITY
108 wxSocketState() : wxObject() {}
110 DECLARE_NO_COPY_CLASS(wxSocketState
)
113 // ==========================================================================
115 // ==========================================================================
117 // --------------------------------------------------------------------------
118 // Initialization and shutdown
119 // --------------------------------------------------------------------------
121 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
122 // to m_countInit with a crit section
123 size_t wxSocketBase::m_countInit
= 0;
125 bool wxSocketBase::IsInitialized()
127 return m_countInit
> 0;
130 bool wxSocketBase::Initialize()
132 if ( !m_countInit
++ )
134 if ( !GSocket_Init() )
145 void wxSocketBase::Shutdown()
147 // we should be initialized
148 wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") );
149 if ( !--m_countInit
)
155 // --------------------------------------------------------------------------
157 // --------------------------------------------------------------------------
159 void wxSocketBase::Init()
162 m_type
= wxSOCKET_UNINIT
;
173 m_beingDeleted
= FALSE
;
186 #if WXWIN_COMPATIBILITY
189 #endif // WXWIN_COMPATIBILITY
191 if ( !IsInitialized() )
193 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
194 // other calls to it should be matched by a call to Shutdown()
199 wxSocketBase::wxSocketBase()
204 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
212 wxSocketBase::~wxSocketBase()
214 // Just in case the app called Destroy() *and* then deleted
215 // the socket immediately: don't leave dangling pointers.
217 wxPendingDelete
.DeleteObject(this);
220 // Shutdown and close the socket
224 // Destroy the GSocket object
226 GSocket_destroy(m_socket
);
228 // Free the pushback buffer
233 bool wxSocketBase::Destroy()
235 // Delayed destruction: the socket will be deleted during the next
236 // idle loop iteration. This ensures that all pending events have
238 m_beingDeleted
= TRUE
;
240 // Shutdown and close the socket
243 // Supress events from now on
247 if ( !wxPendingDelete
.Member(this) )
248 wxPendingDelete
.Append(this);
256 // --------------------------------------------------------------------------
258 // --------------------------------------------------------------------------
260 // The following IO operations update m_error and m_lcount:
261 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
263 // TODO: Should Connect, Accept and AcceptWith update m_error?
265 bool wxSocketBase::Close()
267 // Interrupt pending waits
273 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
274 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
276 // Shutdown the connection
277 GSocket_Shutdown(m_socket
);
281 m_establishing
= FALSE
;
285 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
290 m_lcount
= _Read(buffer
, nbytes
);
292 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
293 if (m_flags
& wxSOCKET_WAITALL
)
294 m_error
= (m_lcount
!= nbytes
);
296 m_error
= (m_lcount
== 0);
298 // Allow read events from now on
304 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
309 // Try the pushback buffer first
310 total
= GetPushback(buffer
, nbytes
, FALSE
);
312 buffer
= (char *)buffer
+ total
;
314 // Return now in one of the following cases:
315 // - the socket is invalid,
316 // - we got all the data,
317 // - we got *some* data and we are not using wxSOCKET_WAITALL.
320 ((total
!= 0) && !(m_flags
& wxSOCKET_WAITALL
)) )
323 // Possible combinations (they are checked in this order)
325 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
329 if (m_flags
& wxSOCKET_NOWAIT
)
331 GSocket_SetNonBlocking(m_socket
, 1);
332 ret
= GSocket_Read(m_socket
, (char *)buffer
, nbytes
);
333 GSocket_SetNonBlocking(m_socket
, 0);
344 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
347 ret
= GSocket_Read(m_socket
, (char *)buffer
, nbytes
);
353 buffer
= (char *)buffer
+ ret
;
356 // If we got here and wxSOCKET_WAITALL is not set, we can leave
357 // now. Otherwise, wait until we recv all the data or until there
360 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
367 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
369 wxUint32 len
, len2
, sig
, total
;
374 unsigned char sig
[4];
375 unsigned char len
[4];
384 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
386 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
389 sig
= (wxUint32
)msg
.sig
[0];
390 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
391 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
392 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
394 if (sig
!= 0xfeeddead)
396 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
400 len
= (wxUint32
)msg
.len
[0];
401 len
|= (wxUint32
)(msg
.len
[1] << 8);
402 len
|= (wxUint32
)(msg
.len
[2] << 16);
403 len
|= (wxUint32
)(msg
.len
[3] << 24);
413 // Don't attemp to read if the msg was zero bytes long.
416 total
= _Read(buffer
, len
);
423 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
426 // NOTE: discarded bytes don't add to m_lcount.
429 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
430 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
431 len2
-= (wxUint32
)discard_len
;
433 while ((discard_len
> 0) && len2
);
435 delete [] discard_buffer
;
440 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
443 sig
= (wxUint32
)msg
.sig
[0];
444 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
445 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
446 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
448 if (sig
!= 0xdeadfeed)
450 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
466 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
471 m_lcount
= _Read(buffer
, nbytes
);
472 Pushback(buffer
, m_lcount
);
474 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
475 if (m_flags
& wxSOCKET_WAITALL
)
476 m_error
= (m_lcount
!= nbytes
);
478 m_error
= (m_lcount
== 0);
480 // Allow read events again
486 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
491 m_lcount
= _Write(buffer
, nbytes
);
493 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
494 if (m_flags
& wxSOCKET_WAITALL
)
495 m_error
= (m_lcount
!= nbytes
);
497 m_error
= (m_lcount
== 0);
499 // Allow write events again
505 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
510 // If the socket is invalid or parameters are ill, return immediately
511 if (!m_socket
|| !buffer
|| !nbytes
)
514 // Possible combinations (they are checked in this order)
516 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
520 if (m_flags
& wxSOCKET_NOWAIT
)
522 GSocket_SetNonBlocking(m_socket
, 1);
523 ret
= GSocket_Write(m_socket
, (const char *)buffer
, nbytes
);
524 GSocket_SetNonBlocking(m_socket
, 0);
535 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
538 ret
= GSocket_Write(m_socket
, (const char *)buffer
, nbytes
);
544 buffer
= (const char *)buffer
+ ret
;
547 // If we got here and wxSOCKET_WAITALL is not set, we can leave
548 // now. Otherwise, wait until we send all the data or until there
551 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
558 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
565 unsigned char sig
[4];
566 unsigned char len
[4];
575 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
577 msg
.sig
[0] = (unsigned char) 0xad;
578 msg
.sig
[1] = (unsigned char) 0xde;
579 msg
.sig
[2] = (unsigned char) 0xed;
580 msg
.sig
[3] = (unsigned char) 0xfe;
582 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
583 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
584 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
585 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
587 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
590 total
= _Write(buffer
, nbytes
);
595 msg
.sig
[0] = (unsigned char) 0xed;
596 msg
.sig
[1] = (unsigned char) 0xfe;
597 msg
.sig
[2] = (unsigned char) 0xad;
598 msg
.sig
[3] = (unsigned char) 0xde;
599 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
601 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
615 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
618 Pushback(buffer
, nbytes
);
626 wxSocketBase
& wxSocketBase::Discard()
629 char *buffer
= new char[MAX_DISCARD_SIZE
];
637 SetFlags(wxSOCKET_NOWAIT
);
641 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
644 while (ret
== MAX_DISCARD_SIZE
);
650 // Allow read events again
656 // --------------------------------------------------------------------------
658 // --------------------------------------------------------------------------
660 // All Wait functions poll the socket using GSocket_Select() to
661 // check for the specified combination of conditions, until one
662 // of these conditions become true, an error occurs, or the
663 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
664 // this won't block the GUI.
666 bool wxSocketBase::_Wait(long seconds
,
668 wxSocketEventFlags flags
)
670 GSocketEventFlags result
;
673 // Set this to TRUE to interrupt ongoing waits
676 // Check for valid socket
680 // Check for valid timeout value.
682 timeout
= seconds
* 1000 + milliseconds
;
684 timeout
= m_timeout
* 1000;
686 // Wait in an active polling loop.
688 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
689 // hurt. It has to be here because the (GSocket) event might arrive
690 // a bit delayed, and it has to be in OnRequest as well because we
691 // don't know whether the Wait functions are being used.
693 // Do this at least once (important if timeout == 0, when
694 // we are just polling). Also, if just polling, do not yield.
701 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
703 // Incoming connection (server) or connection established (client)
704 if (result
& GSOCK_CONNECTION_FLAG
)
707 m_establishing
= FALSE
;
711 // Data available or output buffer ready
712 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
718 if (result
& GSOCK_LOST_FLAG
)
721 m_establishing
= FALSE
;
722 return (flags
& GSOCK_LOST_FLAG
) != 0;
726 if ((!timeout
) || (chrono
.Time() > timeout
) || (m_interrupt
))
735 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
737 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
739 GSOCK_CONNECTION_FLAG
|
743 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
745 // Check pushback buffer before entering _Wait
749 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
750 // _Wait becuase of the semantics of WaitForRead: a return
751 // value of TRUE means that a GSocket_Read call will return
752 // immediately, not that there is actually data to read.
754 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
758 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
760 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
763 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
765 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
768 // --------------------------------------------------------------------------
770 // --------------------------------------------------------------------------
773 // Get local or peer address
776 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
783 peer
= GSocket_GetPeer(m_socket
);
785 // copying a null address would just trigger an assert anyway
790 addr_man
.SetAddress(peer
);
791 GAddress_destroy(peer
);
796 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
803 local
= GSocket_GetLocal(m_socket
);
804 addr_man
.SetAddress(local
);
805 GAddress_destroy(local
);
811 // Save and restore socket state
814 void wxSocketBase::SaveState()
816 wxSocketState
*state
;
818 state
= new wxSocketState();
820 state
->m_flags
= m_flags
;
821 state
->m_notify
= m_notify
;
822 state
->m_eventmask
= m_eventmask
;
823 state
->m_clientData
= m_clientData
;
824 #if WXWIN_COMPATIBILITY
825 state
->m_cbk
= m_cbk
;
826 state
->m_cdata
= m_cdata
;
827 #endif // WXWIN_COMPATIBILITY
829 m_states
.Append(state
);
832 void wxSocketBase::RestoreState()
835 wxSocketState
*state
;
837 node
= m_states
.GetLast();
841 state
= (wxSocketState
*)node
->GetData();
843 m_flags
= state
->m_flags
;
844 m_notify
= state
->m_notify
;
845 m_eventmask
= state
->m_eventmask
;
846 m_clientData
= state
->m_clientData
;
847 #if WXWIN_COMPATIBILITY
848 m_cbk
= state
->m_cbk
;
849 m_cdata
= state
->m_cdata
;
850 #endif // WXWIN_COMPATIBILITY
860 void wxSocketBase::SetTimeout(long seconds
)
865 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
868 void wxSocketBase::SetFlags(wxSocketFlags flags
)
874 // --------------------------------------------------------------------------
875 // Callbacks (now obsolete - use events instead)
876 // --------------------------------------------------------------------------
878 #if WXWIN_COMPATIBILITY
880 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
882 wxSockCbk old_cbk
= cbk_
;
888 char *wxSocketBase::CallbackData(char *data
)
890 char *old_data
= m_cdata
;
896 #endif // WXWIN_COMPATIBILITY
898 // --------------------------------------------------------------------------
900 // --------------------------------------------------------------------------
902 // A note on how events are processed, which is probably the most
903 // difficult thing to get working right while keeping the same API
904 // and functionality for all platforms.
906 // When GSocket detects an event, it calls wx_socket_callback, which in
907 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
908 // object. OnRequest does some housekeeping, and if the event is to be
909 // propagated to the user, it creates a new wxSocketEvent object and
910 // posts it. The event is not processed immediately, but delayed with
911 // AddPendingEvent instead. This is necessary in order to decouple the
912 // event processing from wx_socket_callback; otherwise, subsequent IO
913 // calls made from the user event handler would fail, as gtk callbacks
914 // are not reentrant.
916 // Note that, unlike events, user callbacks (now deprecated) are _not_
917 // decoupled from wx_socket_callback and thus they suffer from a variety
918 // of problems. Avoid them where possible and use events instead.
921 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
922 GSocketEvent notification
,
925 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
927 sckobj
->OnRequest((wxSocketNotify
) notification
);
930 void wxSocketBase::OnRequest(wxSocketNotify notification
)
932 // NOTE: We duplicate some of the code in _Wait, but this doesn't
933 // hurt. It has to be here because the (GSocket) event might arrive
934 // a bit delayed, and it has to be in _Wait as well because we don't
935 // know whether the Wait functions are being used.
939 case wxSOCKET_CONNECTION
:
940 m_establishing
= FALSE
;
944 // If we are in the middle of a R/W operation, do not
945 // propagate events to users. Also, filter 'late' events
946 // which are no longer valid.
949 if (m_reading
|| !GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
953 case wxSOCKET_OUTPUT
:
954 if (m_writing
|| !GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
))
960 m_establishing
= FALSE
;
967 // Schedule the event
969 wxSocketEventFlags flag
= 0;
970 switch (notification
)
972 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
973 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
974 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
975 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
977 wxLogWarning(_("wxSocket: unknown event!."));
981 if (((m_eventmask
& flag
) == flag
) && m_notify
)
985 wxSocketEvent
event(m_id
);
986 event
.m_event
= notification
;
987 event
.m_clientData
= m_clientData
;
988 event
.SetEventObject(this);
990 m_handler
->AddPendingEvent(event
);
993 #if WXWIN_COMPATIBILITY
995 m_cbk(*this, notification
, m_cdata
);
996 #endif // WXWIN_COMPATIBILITY
1000 void wxSocketBase::Notify(bool notify
)
1005 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1007 m_eventmask
= flags
;
1010 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1012 m_handler
= &handler
;
1016 // --------------------------------------------------------------------------
1018 // --------------------------------------------------------------------------
1020 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1024 if (m_unread
== NULL
)
1025 m_unread
= malloc(size
);
1030 tmp
= malloc(m_unrd_size
+ size
);
1031 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1037 m_unrd_size
+= size
;
1039 memcpy(m_unread
, buffer
, size
);
1042 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1047 if (size
> (m_unrd_size
-m_unrd_cur
))
1048 size
= m_unrd_size
-m_unrd_cur
;
1050 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1055 if (m_unrd_size
== m_unrd_cur
)
1068 // ==========================================================================
1070 // ==========================================================================
1072 // --------------------------------------------------------------------------
1074 // --------------------------------------------------------------------------
1076 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
1077 wxSocketFlags flags
)
1078 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1080 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1082 m_socket
= GSocket_new();
1086 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1090 // Setup the socket as server
1092 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
1093 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
1095 GSocket_destroy(m_socket
);
1098 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1102 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1103 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1104 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1105 wx_socket_callback
, (char *)this);
1108 // --------------------------------------------------------------------------
1110 // --------------------------------------------------------------------------
1112 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1114 GSocket
*child_socket
;
1119 // If wait == FALSE, then the call should be nonblocking.
1120 // When we are finished, we put the socket to blocking mode
1124 GSocket_SetNonBlocking(m_socket
, 1);
1126 child_socket
= GSocket_WaitConnection(m_socket
);
1129 GSocket_SetNonBlocking(m_socket
, 0);
1134 sock
.m_type
= wxSOCKET_BASE
;
1135 sock
.m_socket
= child_socket
;
1136 sock
.m_connected
= TRUE
;
1138 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
* 1000);
1139 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1140 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1141 wx_socket_callback
, (char *)&sock
);
1146 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1148 wxSocketBase
* sock
= new wxSocketBase();
1150 sock
->SetFlags(m_flags
);
1152 if (!AcceptWith(*sock
, wait
))
1161 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1163 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1166 // ==========================================================================
1168 // ==========================================================================
1170 // --------------------------------------------------------------------------
1172 // --------------------------------------------------------------------------
1174 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1175 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1179 wxSocketClient::~wxSocketClient()
1183 // --------------------------------------------------------------------------
1185 // --------------------------------------------------------------------------
1187 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1193 // Shutdown and destroy the socket
1195 GSocket_destroy(m_socket
);
1198 m_socket
= GSocket_new();
1199 m_connected
= FALSE
;
1200 m_establishing
= FALSE
;
1205 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1206 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1207 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1208 wx_socket_callback
, (char *)this);
1210 // If wait == FALSE, then the call should be nonblocking.
1211 // When we are finished, we put the socket to blocking mode
1215 GSocket_SetNonBlocking(m_socket
, 1);
1217 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1218 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1221 GSocket_SetNonBlocking(m_socket
, 0);
1223 if (err
!= GSOCK_NOERROR
)
1225 if (err
== GSOCK_WOULDBLOCK
)
1226 m_establishing
= TRUE
;
1235 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1237 if (m_connected
) // Already connected
1240 if (!m_establishing
|| !m_socket
) // No connection in progress
1243 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1247 // ==========================================================================
1249 // ==========================================================================
1251 /* NOTE: experimental stuff - might change */
1253 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
,
1254 wxSocketFlags flags
)
1255 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1257 // Create the socket
1258 m_socket
= GSocket_new();
1263 // Setup the socket as non connection oriented
1264 GSocket_SetLocal(m_socket
, addr
.GetAddress());
1265 if( GSocket_SetNonOriented(m_socket
) != GSOCK_NOERROR
)
1267 GSocket_destroy(m_socket
);
1272 // Initialize all stuff
1273 m_connected
= FALSE
;
1274 m_establishing
= FALSE
;
1275 GSocket_SetTimeout( m_socket
, m_timeout
);
1276 GSocket_SetCallback( m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1277 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1278 wx_socket_callback
, (char*)this );
1282 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1291 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1295 GSocket_SetPeer(m_socket
, addr
.GetAddress());
1300 // ==========================================================================
1302 // ==========================================================================
1304 class WXDLLEXPORT wxSocketModule
: public wxModule
1307 virtual bool OnInit()
1309 // wxSocketBase will call GSocket_Init() itself when/if needed
1313 virtual void OnExit()
1315 if ( wxSocketBase::IsInitialized() )
1316 wxSocketBase::Shutdown();
1320 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1323 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)