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/datetime.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
== 0 )
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 bool has_event_loop
= wxTheApp
? (wxTheApp
->GetTraits() ? true : false) : false;
699 // Wait in an active polling loop.
701 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
702 // hurt. It has to be here because the (GSocket) event might arrive
703 // a bit delayed, and it has to be in OnRequest as well because we
704 // don't know whether the Wait functions are being used.
706 // Do this at least once (important if timeout == 0, when
707 // we are just polling). Also, if just polling, do not yield.
709 wxDateTime current_time
= wxDateTime::UNow();
710 unsigned int time_limit
= (current_time
.GetTicks() * 1000) + current_time
.GetMillisecond() + timeout
;
712 bool valid_result
= false;
716 // This is used to avoid a busy loop on wxBase - having a select
717 // timeout of 50 ms per iteration should be enough.
719 m_socket
->SetTimeout(50);
721 m_socket
->SetTimeout(timeout
);
726 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
728 // Incoming connection (server) or connection established (client)
729 if (result
& GSOCK_CONNECTION_FLAG
)
732 m_establishing
= false;
737 // Data available or output buffer ready
738 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
745 if (result
& GSOCK_LOST_FLAG
)
748 m_establishing
= false;
749 valid_result
= ((flags
& GSOCK_LOST_FLAG
) != 0);
754 current_time
= wxDateTime::UNow();
755 int time_left
= time_limit
- ((current_time
.GetTicks() * 1000) + current_time
.GetMillisecond());
756 if ((!timeout
) || (time_left
<= 0) || (m_interrupt
))
766 // If there's less than 50 ms left, just call select with that timeout.
768 m_socket
->SetTimeout(time_left
);
773 // Set timeout back to original value (we overwrote it for polling)
775 m_socket
->SetTimeout(m_timeout
*1000);
780 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
782 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
784 GSOCK_CONNECTION_FLAG
|
788 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
790 // Check pushback buffer before entering _Wait
794 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
795 // _Wait because of the semantics of WaitForRead: a return
796 // value of true means that a GSocket_Read call will return
797 // immediately, not that there is actually data to read.
799 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
804 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
806 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
809 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
811 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
814 // --------------------------------------------------------------------------
816 // --------------------------------------------------------------------------
819 // Get local or peer address
822 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
829 peer
= m_socket
->GetPeer();
831 // copying a null address would just trigger an assert anyway
836 addr_man
.SetAddress(peer
);
837 GAddress_destroy(peer
);
842 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
849 local
= m_socket
->GetLocal();
850 addr_man
.SetAddress(local
);
851 GAddress_destroy(local
);
857 // Save and restore socket state
860 void wxSocketBase::SaveState()
862 wxSocketState
*state
;
864 state
= new wxSocketState();
866 state
->m_flags
= m_flags
;
867 state
->m_notify
= m_notify
;
868 state
->m_eventmask
= m_eventmask
;
869 state
->m_clientData
= m_clientData
;
871 m_states
.Append(state
);
874 void wxSocketBase::RestoreState()
876 wxList::compatibility_iterator node
;
877 wxSocketState
*state
;
879 node
= m_states
.GetLast();
883 state
= (wxSocketState
*)node
->GetData();
885 m_flags
= state
->m_flags
;
886 m_notify
= state
->m_notify
;
887 m_eventmask
= state
->m_eventmask
;
888 m_clientData
= state
->m_clientData
;
890 m_states
.Erase(node
);
898 void wxSocketBase::SetTimeout(long seconds
)
903 m_socket
->SetTimeout(m_timeout
* 1000);
906 void wxSocketBase::SetFlags(wxSocketFlags flags
)
912 // --------------------------------------------------------------------------
914 // --------------------------------------------------------------------------
916 // A note on how events are processed, which is probably the most
917 // difficult thing to get working right while keeping the same API
918 // and functionality for all platforms.
920 // When GSocket detects an event, it calls wx_socket_callback, which in
921 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
922 // object. OnRequest does some housekeeping, and if the event is to be
923 // propagated to the user, it creates a new wxSocketEvent object and
924 // posts it. The event is not processed immediately, but delayed with
925 // AddPendingEvent instead. This is necessary in order to decouple the
926 // event processing from wx_socket_callback; otherwise, subsequent IO
927 // calls made from the user event handler would fail, as gtk callbacks
928 // are not reentrant.
930 // Note that, unlike events, user callbacks (now deprecated) are _not_
931 // decoupled from wx_socket_callback and thus they suffer from a variety
932 // of problems. Avoid them where possible and use events instead.
935 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
936 GSocketEvent notification
,
939 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
941 sckobj
->OnRequest((wxSocketNotify
) notification
);
944 void wxSocketBase::OnRequest(wxSocketNotify notification
)
946 // NOTE: We duplicate some of the code in _Wait, but this doesn't
947 // hurt. It has to be here because the (GSocket) event might arrive
948 // a bit delayed, and it has to be in _Wait as well because we don't
949 // know whether the Wait functions are being used.
953 case wxSOCKET_CONNECTION
:
954 m_establishing
= false;
958 // If we are in the middle of a R/W operation, do not
959 // propagate events to users. Also, filter 'late' events
960 // which are no longer valid.
963 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
967 case wxSOCKET_OUTPUT
:
968 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
974 m_establishing
= false;
981 // Schedule the event
983 wxSocketEventFlags flag
= 0;
985 switch (notification
)
987 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
988 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
989 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
990 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
992 wxLogWarning(_("wxSocket: unknown event!."));
996 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1000 wxSocketEvent
event(m_id
);
1001 event
.m_event
= notification
;
1002 event
.m_clientData
= m_clientData
;
1003 event
.SetEventObject(this);
1005 m_handler
->AddPendingEvent(event
);
1010 void wxSocketBase::Notify(bool notify
)
1015 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1017 m_eventmask
= flags
;
1020 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1022 m_handler
= &handler
;
1026 // --------------------------------------------------------------------------
1028 // --------------------------------------------------------------------------
1030 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1034 if (m_unread
== NULL
)
1035 m_unread
= malloc(size
);
1040 tmp
= malloc(m_unrd_size
+ size
);
1041 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1047 m_unrd_size
+= size
;
1049 memcpy(m_unread
, buffer
, size
);
1052 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1057 if (size
> (m_unrd_size
-m_unrd_cur
))
1058 size
= m_unrd_size
-m_unrd_cur
;
1060 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1065 if (m_unrd_size
== m_unrd_cur
)
1078 // ==========================================================================
1080 // ==========================================================================
1082 // --------------------------------------------------------------------------
1084 // --------------------------------------------------------------------------
1086 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1087 wxSocketFlags flags
)
1088 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1090 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1092 m_socket
= GSocket_new();
1096 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1100 // Setup the socket as server
1102 m_socket
->SetLocal(addr_man
.GetAddress());
1104 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1105 m_socket
->SetReusable();
1108 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1113 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1117 m_socket
->SetTimeout(m_timeout
* 1000);
1118 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1119 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1120 wx_socket_callback
, (char *)this);
1123 // --------------------------------------------------------------------------
1125 // --------------------------------------------------------------------------
1127 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1129 GSocket
*child_socket
;
1134 // If wait == false, then the call should be nonblocking.
1135 // When we are finished, we put the socket to blocking mode
1139 m_socket
->SetNonBlocking(1);
1141 child_socket
= m_socket
->WaitConnection();
1144 m_socket
->SetNonBlocking(0);
1149 sock
.m_type
= wxSOCKET_BASE
;
1150 sock
.m_socket
= child_socket
;
1151 sock
.m_connected
= true;
1153 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1154 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1155 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1156 wx_socket_callback
, (char *)&sock
);
1161 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1163 wxSocketBase
* sock
= new wxSocketBase();
1165 sock
->SetFlags(m_flags
);
1167 if (!AcceptWith(*sock
, wait
))
1176 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1178 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1181 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1183 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1185 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1193 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1196 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1198 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1206 bool wxSocketBase::SetLocal(wxSockAddress
& local
)
1208 GAddress
* la
= local
.GetAddress();
1210 if (la
&& la
->m_addr
)
1212 m_socket
->SetLocal(la
);
1220 // ==========================================================================
1222 // ==========================================================================
1224 // --------------------------------------------------------------------------
1226 // --------------------------------------------------------------------------
1228 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1229 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1233 wxSocketClient::~wxSocketClient()
1237 // --------------------------------------------------------------------------
1239 // --------------------------------------------------------------------------
1241 bool wxSocketClient::DoConnect(wxSockAddress
& addr_man
, wxSockAddress
* local
, bool wait
)
1247 // Shutdown and destroy the socket
1252 m_socket
= GSocket_new();
1253 m_connected
= false;
1254 m_establishing
= false;
1259 m_socket
->SetTimeout(m_timeout
* 1000);
1260 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1261 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1262 wx_socket_callback
, (char *)this);
1264 // If wait == false, then the call should be nonblocking.
1265 // When we are finished, we put the socket to blocking mode
1269 m_socket
->SetNonBlocking(1);
1271 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1272 if (GetFlags() & wxSOCKET_REUSEADDR
)
1274 m_socket
->SetReusable();
1277 // Bind to the local IP address and port, when provided
1280 GAddress
* la
= local
->GetAddress();
1282 if (la
&& la
->m_addr
)
1283 m_socket
->SetLocal(la
);
1286 m_socket
->SetPeer(addr_man
.GetAddress());
1287 err
= m_socket
->Connect(GSOCK_STREAMED
);
1290 m_socket
->SetNonBlocking(0);
1292 if (err
!= GSOCK_NOERROR
)
1294 if (err
== GSOCK_WOULDBLOCK
)
1295 m_establishing
= true;
1304 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1306 return (DoConnect(addr_man
, NULL
, wait
));
1309 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, wxSockAddress
& local
, bool wait
)
1311 return (DoConnect(addr_man
, &local
, wait
));
1314 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1316 if (m_connected
) // Already connected
1319 if (!m_establishing
|| !m_socket
) // No connection in progress
1322 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1326 // ==========================================================================
1328 // ==========================================================================
1330 /* NOTE: experimental stuff - might change */
1332 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1333 wxSocketFlags flags
)
1334 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1336 // Create the socket
1337 m_socket
= GSocket_new();
1341 wxASSERT_MSG( 0, _T("datagram socket not new'd") );
1344 // Setup the socket as non connection oriented
1345 m_socket
->SetLocal(addr
.GetAddress());
1346 if( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1353 // Initialize all stuff
1354 m_connected
= false;
1355 m_establishing
= false;
1356 m_socket
->SetTimeout( m_timeout
);
1357 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1358 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1359 wx_socket_callback
, (char*)this );
1363 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1372 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1376 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1378 m_socket
->SetPeer(addr
.GetAddress());
1383 // ==========================================================================
1385 // ==========================================================================
1387 class wxSocketModule
: public wxModule
1390 virtual bool OnInit()
1392 // wxSocketBase will call GSocket_Init() itself when/if needed
1396 virtual void OnExit()
1398 if ( wxSocketBase::IsInitialized() )
1399 wxSocketBase::Shutdown();
1403 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1406 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)