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 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
26 #include "wx/apptrait.h"
28 #include "wx/object.h"
29 #include "wx/string.h"
32 #include "wx/module.h"
37 #include "wx/sckaddr.h"
38 #include "wx/socket.h"
39 #include "wx/stopwatch.h"
41 // DLL options compatibility check:
43 WX_CHECK_BUILD_OPTIONS("wxNet")
45 // --------------------------------------------------------------------------
46 // macros and constants
47 // --------------------------------------------------------------------------
50 #define MAX_DISCARD_SIZE (10 * 1024)
52 // what to do within waits: we have 2 cases: from the main thread itself we
53 // have to call wxYield() to let the events (including the GUI events and the
54 // low-level (not wxWidgets) events from GSocket) be processed. From another
55 // thread it is enough to just call wxThread::Yield() which will give away the
56 // rest of our time slice: the explanation is that the events will be processed
57 // by the main thread anyhow, without calling wxYield(), but we don't want to
58 // eat the CPU time uselessly while sitting in the loop waiting for the data
60 #define PROCESS_EVENTS() \
62 if ( wxThread::IsMain() ) \
67 #else // !wxUSE_THREADS
68 #define PROCESS_EVENTS() wxYield()
69 #endif // wxUSE_THREADS/!wxUSE_THREADS
71 #define wxTRACE_Socket _T("wxSocket")
73 // --------------------------------------------------------------------------
75 // --------------------------------------------------------------------------
77 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
78 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
79 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
80 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
81 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
83 // --------------------------------------------------------------------------
85 // --------------------------------------------------------------------------
87 class wxSocketState
: public wxObject
90 wxSocketFlags m_flags
;
91 wxSocketEventFlags m_eventmask
;
96 wxSocketState() : wxObject() {}
98 DECLARE_NO_COPY_CLASS(wxSocketState
)
101 // ==========================================================================
103 // ==========================================================================
105 // --------------------------------------------------------------------------
106 // Initialization and shutdown
107 // --------------------------------------------------------------------------
109 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
110 // to m_countInit with a crit section
111 size_t wxSocketBase::m_countInit
= 0;
113 bool wxSocketBase::IsInitialized()
115 return m_countInit
> 0;
118 bool wxSocketBase::Initialize()
120 if ( !m_countInit
++ )
123 Details: Initialize() creates a hidden window as a sink for socket
124 events, such as 'read completed'. wxMSW has only one message loop
125 for the main thread. If Initialize is called in a secondary thread,
126 the socket window will be created for the secondary thread, but
127 since there is no message loop on this thread, it will never
128 receive events and all socket operations will time out.
129 BTW, the main thread must not be stopped using sleep or block
130 on a semaphore (a bad idea in any case) or socket operations
133 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
134 the main thread. Because secondary threads do not have run loops,
135 adding event notifications to the "Current" loop would have no
136 effect at all, events would never fire.
138 wxASSERT_MSG( wxIsMainThread(),
139 wxT("Call wxSocketBase::Initialize() from the main thread first!"));
141 wxAppTraits
*traits
= wxAppConsole::GetInstance() ?
142 wxAppConsole::GetInstance()->GetTraits() : NULL
;
143 GSocketGUIFunctionsTable
*functions
=
144 traits
? traits
->GetSocketGUIFunctionsTable() : NULL
;
145 GSocket_SetGUIFunctions(functions
);
147 if ( !GSocket_Init() )
158 void wxSocketBase::Shutdown()
160 // we should be initialized
161 wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") );
162 if ( !--m_countInit
)
168 // --------------------------------------------------------------------------
170 // --------------------------------------------------------------------------
172 void wxSocketBase::Init()
175 m_type
= wxSOCKET_UNINIT
;
186 m_beingDeleted
= false;
200 if ( !IsInitialized() )
202 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
203 // other calls to it should be matched by a call to Shutdown()
208 wxSocketBase::wxSocketBase()
213 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
221 wxSocketBase::~wxSocketBase()
223 // Just in case the app called Destroy() *and* then deleted
224 // the socket immediately: don't leave dangling pointers.
225 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
227 traits
->RemoveFromPendingDelete(this);
229 // Shutdown and close the socket
233 // Destroy the GSocket object
237 // Free the pushback buffer
242 bool wxSocketBase::Destroy()
244 // Delayed destruction: the socket will be deleted during the next
245 // idle loop iteration. This ensures that all pending events have
247 m_beingDeleted
= true;
249 // Shutdown and close the socket
252 // Supress events from now on
255 // schedule this object for deletion
256 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
259 // let the traits object decide what to do with us
260 traits
->ScheduleForDestroy(this);
262 else // no app or no traits
264 // in wxBase we might have no app object at all, don't leak memory
271 // --------------------------------------------------------------------------
273 // --------------------------------------------------------------------------
275 // The following IO operations update m_error and m_lcount:
276 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
278 // TODO: Should Connect, Accept and AcceptWith update m_error?
280 bool wxSocketBase::Close()
282 // Interrupt pending waits
288 m_socket
->UnsetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
289 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
291 // Shutdown the connection
292 m_socket
->Shutdown();
296 m_establishing
= false;
300 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
305 m_lcount
= _Read(buffer
, nbytes
);
307 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
308 if (m_flags
& wxSOCKET_WAITALL
)
309 m_error
= (m_lcount
!= nbytes
);
311 m_error
= (m_lcount
== 0);
313 // Allow read events from now on
319 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
323 // Try the pushback buffer first
324 total
= GetPushback(buffer
, nbytes
, false);
326 buffer
= (char *)buffer
+ total
;
328 // Return now in one of the following cases:
329 // - the socket is invalid,
330 // - we got all the data,
331 // - we got *some* data and we are not using wxSOCKET_WAITALL.
334 ((total
!= 0) && !(m_flags
& wxSOCKET_WAITALL
)) )
337 // Possible combinations (they are checked in this order)
339 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
344 if (m_flags
& wxSOCKET_NOWAIT
)
346 m_socket
->SetNonBlocking(1);
347 ret
= m_socket
->Read((char *)buffer
, nbytes
);
348 m_socket
->SetNonBlocking(0);
359 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
362 ret
= m_socket
->Read((char *)buffer
, nbytes
);
368 buffer
= (char *)buffer
+ ret
;
371 // If we got here and wxSOCKET_WAITALL is not set, we can leave
372 // now. Otherwise, wait until we recv all the data or until there
375 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
382 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
384 wxUint32 len
, len2
, sig
, total
;
389 unsigned char sig
[4];
390 unsigned char len
[4];
399 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
401 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
404 sig
= (wxUint32
)msg
.sig
[0];
405 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
406 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
407 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
409 if (sig
!= 0xfeeddead)
411 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
415 len
= (wxUint32
)msg
.len
[0];
416 len
|= (wxUint32
)(msg
.len
[1] << 8);
417 len
|= (wxUint32
)(msg
.len
[2] << 16);
418 len
|= (wxUint32
)(msg
.len
[3] << 24);
428 // Don't attemp to read if the msg was zero bytes long.
431 total
= _Read(buffer
, len
);
438 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
441 // NOTE: discarded bytes don't add to m_lcount.
444 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
445 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
446 len2
-= (wxUint32
)discard_len
;
448 while ((discard_len
> 0) && len2
);
450 delete [] discard_buffer
;
455 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
458 sig
= (wxUint32
)msg
.sig
[0];
459 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
460 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
461 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
463 if (sig
!= 0xdeadfeed)
465 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
481 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
486 m_lcount
= _Read(buffer
, nbytes
);
487 Pushback(buffer
, m_lcount
);
489 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
490 if (m_flags
& wxSOCKET_WAITALL
)
491 m_error
= (m_lcount
!= nbytes
);
493 m_error
= (m_lcount
== 0);
495 // Allow read events again
501 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
506 m_lcount
= _Write(buffer
, nbytes
);
508 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
509 if (m_flags
& wxSOCKET_WAITALL
)
510 m_error
= (m_lcount
!= nbytes
);
512 m_error
= (m_lcount
== 0);
514 // Allow write events again
520 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
524 // If the socket is invalid or parameters are ill, return immediately
525 if (!m_socket
|| !buffer
|| !nbytes
)
528 // Possible combinations (they are checked in this order)
530 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
535 if (m_flags
& wxSOCKET_NOWAIT
)
537 m_socket
->SetNonBlocking(1);
538 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
539 m_socket
->SetNonBlocking(0);
550 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
553 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
559 buffer
= (const char *)buffer
+ ret
;
562 // If we got here and wxSOCKET_WAITALL is not set, we can leave
563 // now. Otherwise, wait until we send all the data or until there
566 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
573 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
579 unsigned char sig
[4];
580 unsigned char len
[4];
588 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
590 msg
.sig
[0] = (unsigned char) 0xad;
591 msg
.sig
[1] = (unsigned char) 0xde;
592 msg
.sig
[2] = (unsigned char) 0xed;
593 msg
.sig
[3] = (unsigned char) 0xfe;
595 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
596 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
597 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
598 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
600 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
603 total
= _Write(buffer
, nbytes
);
608 msg
.sig
[0] = (unsigned char) 0xed;
609 msg
.sig
[1] = (unsigned char) 0xfe;
610 msg
.sig
[2] = (unsigned char) 0xad;
611 msg
.sig
[3] = (unsigned char) 0xde;
612 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
614 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
628 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
631 Pushback(buffer
, nbytes
);
639 wxSocketBase
& wxSocketBase::Discard()
641 char *buffer
= new char[MAX_DISCARD_SIZE
];
648 SetFlags(wxSOCKET_NOWAIT
);
652 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
655 while (ret
== MAX_DISCARD_SIZE
);
661 // Allow read events again
667 // --------------------------------------------------------------------------
669 // --------------------------------------------------------------------------
671 // All Wait functions poll the socket using GSocket_Select() to
672 // check for the specified combination of conditions, until one
673 // of these conditions become true, an error occurs, or the
674 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
675 // this won't block the GUI.
677 bool wxSocketBase::_Wait(long seconds
,
679 wxSocketEventFlags flags
)
681 GSocketEventFlags result
;
684 // Set this to true to interrupt ongoing waits
687 // Check for valid socket
691 // Check for valid timeout value.
693 timeout
= seconds
* 1000 + milliseconds
;
695 timeout
= m_timeout
* 1000;
697 #if !defined(wxUSE_GUI) || !wxUSE_GUI
698 m_socket
->SetTimeout(timeout
);
701 // Wait in an active polling loop.
703 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
704 // hurt. It has to be here because the (GSocket) event might arrive
705 // a bit delayed, and it has to be in OnRequest as well because we
706 // don't know whether the Wait functions are being used.
708 // Do this at least once (important if timeout == 0, when
709 // we are just polling). Also, if just polling, do not yield.
716 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
718 // Incoming connection (server) or connection established (client)
719 if (result
& GSOCK_CONNECTION_FLAG
)
722 m_establishing
= false;
726 // Data available or output buffer ready
727 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
733 if (result
& GSOCK_LOST_FLAG
)
736 m_establishing
= false;
737 return (flags
& GSOCK_LOST_FLAG
) != 0;
741 if ((!timeout
) || (chrono
.Time() > timeout
) || (m_interrupt
))
750 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
752 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
754 GSOCK_CONNECTION_FLAG
|
758 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
760 // Check pushback buffer before entering _Wait
764 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
765 // _Wait becuase of the semantics of WaitForRead: a return
766 // value of true means that a GSocket_Read call will return
767 // immediately, not that there is actually data to read.
769 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
774 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
776 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
779 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
781 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
784 // --------------------------------------------------------------------------
786 // --------------------------------------------------------------------------
789 // Get local or peer address
792 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
799 peer
= m_socket
->GetPeer();
801 // copying a null address would just trigger an assert anyway
806 addr_man
.SetAddress(peer
);
807 GAddress_destroy(peer
);
812 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
819 local
= m_socket
->GetLocal();
820 addr_man
.SetAddress(local
);
821 GAddress_destroy(local
);
827 // Save and restore socket state
830 void wxSocketBase::SaveState()
832 wxSocketState
*state
;
834 state
= new wxSocketState();
836 state
->m_flags
= m_flags
;
837 state
->m_notify
= m_notify
;
838 state
->m_eventmask
= m_eventmask
;
839 state
->m_clientData
= m_clientData
;
841 m_states
.Append(state
);
844 void wxSocketBase::RestoreState()
846 wxList::compatibility_iterator node
;
847 wxSocketState
*state
;
849 node
= m_states
.GetLast();
853 state
= (wxSocketState
*)node
->GetData();
855 m_flags
= state
->m_flags
;
856 m_notify
= state
->m_notify
;
857 m_eventmask
= state
->m_eventmask
;
858 m_clientData
= state
->m_clientData
;
860 m_states
.Erase(node
);
868 void wxSocketBase::SetTimeout(long seconds
)
873 m_socket
->SetTimeout(m_timeout
* 1000);
876 void wxSocketBase::SetFlags(wxSocketFlags flags
)
882 // --------------------------------------------------------------------------
884 // --------------------------------------------------------------------------
886 // A note on how events are processed, which is probably the most
887 // difficult thing to get working right while keeping the same API
888 // and functionality for all platforms.
890 // When GSocket detects an event, it calls wx_socket_callback, which in
891 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
892 // object. OnRequest does some housekeeping, and if the event is to be
893 // propagated to the user, it creates a new wxSocketEvent object and
894 // posts it. The event is not processed immediately, but delayed with
895 // AddPendingEvent instead. This is necessary in order to decouple the
896 // event processing from wx_socket_callback; otherwise, subsequent IO
897 // calls made from the user event handler would fail, as gtk callbacks
898 // are not reentrant.
900 // Note that, unlike events, user callbacks (now deprecated) are _not_
901 // decoupled from wx_socket_callback and thus they suffer from a variety
902 // of problems. Avoid them where possible and use events instead.
905 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
906 GSocketEvent notification
,
909 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
911 sckobj
->OnRequest((wxSocketNotify
) notification
);
914 void wxSocketBase::OnRequest(wxSocketNotify notification
)
916 // NOTE: We duplicate some of the code in _Wait, but this doesn't
917 // hurt. It has to be here because the (GSocket) event might arrive
918 // a bit delayed, and it has to be in _Wait as well because we don't
919 // know whether the Wait functions are being used.
923 case wxSOCKET_CONNECTION
:
924 m_establishing
= false;
928 // If we are in the middle of a R/W operation, do not
929 // propagate events to users. Also, filter 'late' events
930 // which are no longer valid.
933 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
937 case wxSOCKET_OUTPUT
:
938 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
944 m_establishing
= false;
951 // Schedule the event
953 wxSocketEventFlags flag
= 0;
955 switch (notification
)
957 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
958 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
959 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
960 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
962 wxLogWarning(_("wxSocket: unknown event!."));
966 if (((m_eventmask
& flag
) == flag
) && m_notify
)
970 wxSocketEvent
event(m_id
);
971 event
.m_event
= notification
;
972 event
.m_clientData
= m_clientData
;
973 event
.SetEventObject(this);
975 m_handler
->AddPendingEvent(event
);
980 void wxSocketBase::Notify(bool notify
)
985 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
990 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
992 m_handler
= &handler
;
996 // --------------------------------------------------------------------------
998 // --------------------------------------------------------------------------
1000 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1004 if (m_unread
== NULL
)
1005 m_unread
= malloc(size
);
1010 tmp
= malloc(m_unrd_size
+ size
);
1011 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1017 m_unrd_size
+= size
;
1019 memcpy(m_unread
, buffer
, size
);
1022 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1027 if (size
> (m_unrd_size
-m_unrd_cur
))
1028 size
= m_unrd_size
-m_unrd_cur
;
1030 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1035 if (m_unrd_size
== m_unrd_cur
)
1048 // ==========================================================================
1050 // ==========================================================================
1052 // --------------------------------------------------------------------------
1054 // --------------------------------------------------------------------------
1056 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1057 wxSocketFlags flags
)
1058 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1060 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1062 m_socket
= GSocket_new();
1066 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1070 // Setup the socket as server
1072 m_socket
->SetLocal(addr_man
.GetAddress());
1074 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1075 m_socket
->SetReusable();
1078 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1083 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1087 m_socket
->SetTimeout(m_timeout
* 1000);
1088 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1089 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1090 wx_socket_callback
, (char *)this);
1093 // --------------------------------------------------------------------------
1095 // --------------------------------------------------------------------------
1097 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1099 GSocket
*child_socket
;
1104 // If wait == false, then the call should be nonblocking.
1105 // When we are finished, we put the socket to blocking mode
1109 m_socket
->SetNonBlocking(1);
1111 child_socket
= m_socket
->WaitConnection();
1114 m_socket
->SetNonBlocking(0);
1119 sock
.m_type
= wxSOCKET_BASE
;
1120 sock
.m_socket
= child_socket
;
1121 sock
.m_connected
= true;
1123 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1124 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1125 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1126 wx_socket_callback
, (char *)&sock
);
1131 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1133 wxSocketBase
* sock
= new wxSocketBase();
1135 sock
->SetFlags(m_flags
);
1137 if (!AcceptWith(*sock
, wait
))
1146 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1148 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1151 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1153 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1155 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1163 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1166 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1168 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1176 // ==========================================================================
1178 // ==========================================================================
1180 // --------------------------------------------------------------------------
1182 // --------------------------------------------------------------------------
1184 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1185 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1189 wxSocketClient::~wxSocketClient()
1193 // --------------------------------------------------------------------------
1195 // --------------------------------------------------------------------------
1197 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1203 // Shutdown and destroy the socket
1208 m_socket
= GSocket_new();
1209 m_connected
= false;
1210 m_establishing
= false;
1215 m_socket
->SetTimeout(m_timeout
* 1000);
1216 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1217 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1218 wx_socket_callback
, (char *)this);
1220 // If wait == false, then the call should be nonblocking.
1221 // When we are finished, we put the socket to blocking mode
1225 m_socket
->SetNonBlocking(1);
1227 m_socket
->SetPeer(addr_man
.GetAddress());
1228 err
= m_socket
->Connect(GSOCK_STREAMED
);
1231 m_socket
->SetNonBlocking(0);
1233 if (err
!= GSOCK_NOERROR
)
1235 if (err
== GSOCK_WOULDBLOCK
)
1236 m_establishing
= true;
1245 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1247 if (m_connected
) // Already connected
1250 if (!m_establishing
|| !m_socket
) // No connection in progress
1253 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1257 // ==========================================================================
1259 // ==========================================================================
1261 /* NOTE: experimental stuff - might change */
1263 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1264 wxSocketFlags flags
)
1265 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1267 // Create the socket
1268 m_socket
= GSocket_new();
1272 wxASSERT_MSG( 0, _T("datagram socket not new'd") );
1275 // Setup the socket as non connection oriented
1276 m_socket
->SetLocal(addr
.GetAddress());
1277 if( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1284 // Initialize all stuff
1285 m_connected
= false;
1286 m_establishing
= false;
1287 m_socket
->SetTimeout( m_timeout
);
1288 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1289 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1290 wx_socket_callback
, (char*)this );
1294 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1303 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1307 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1309 m_socket
->SetPeer(addr
.GetAddress());
1314 // ==========================================================================
1316 // ==========================================================================
1318 class wxSocketModule
: public wxModule
1321 virtual bool OnInit()
1323 // wxSocketBase will call GSocket_Init() itself when/if needed
1327 virtual void OnExit()
1329 if ( wxSocketBase::IsInitialized() )
1330 wxSocketBase::Shutdown();
1334 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1337 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)