1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/socket.cpp
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: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ==========================================================================
14 // ==========================================================================
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 #include "wx/socket.h"
28 #include "wx/object.h"
29 #include "wx/string.h"
36 #include "wx/module.h"
39 #include "wx/apptrait.h"
40 #include "wx/sckaddr.h"
41 #include "wx/stopwatch.h"
42 #include "wx/thread.h"
43 #include "wx/evtloop.h"
45 // DLL options compatibility check:
47 WX_CHECK_BUILD_OPTIONS("wxNet")
49 // --------------------------------------------------------------------------
50 // macros and constants
51 // --------------------------------------------------------------------------
54 #define MAX_DISCARD_SIZE (10 * 1024)
56 // what to do within waits: we have 2 cases: from the main thread itself we
57 // have to call wxYield() to let the events (including the GUI events and the
58 // low-level (not wxWidgets) events from GSocket) be processed. From another
59 // thread it is enough to just call wxThread::Yield() which will give away the
60 // rest of our time slice: the explanation is that the events will be processed
61 // by the main thread anyhow, without calling wxYield(), but we don't want to
62 // eat the CPU time uselessly while sitting in the loop waiting for the data
64 #define PROCESS_EVENTS() \
66 if ( wxThread::IsMain() ) \
71 #else // !wxUSE_THREADS
72 #define PROCESS_EVENTS() wxYield()
73 #endif // wxUSE_THREADS/!wxUSE_THREADS
75 #define wxTRACE_Socket _T("wxSocket")
77 // --------------------------------------------------------------------------
79 // --------------------------------------------------------------------------
81 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
82 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
83 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
84 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
85 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
87 // --------------------------------------------------------------------------
89 // --------------------------------------------------------------------------
91 class wxSocketState
: public wxObject
94 wxSocketFlags m_flags
;
95 wxSocketEventFlags m_eventmask
;
100 wxSocketState() : wxObject() {}
102 DECLARE_NO_COPY_CLASS(wxSocketState
)
105 // ============================================================================
107 // ============================================================================
109 GSocketManager
*GSocketManager::ms_manager
= NULL
;
112 void GSocketManager::Set(GSocketManager
*manager
)
114 wxASSERT_MSG( !ms_manager
, "too late to set manager now" );
116 ms_manager
= manager
;
120 void GSocketManager::Init()
122 wxASSERT_MSG( !ms_manager
, "shouldn't be initialized twice" );
125 Details: Initialize() creates a hidden window as a sink for socket
126 events, such as 'read completed'. wxMSW has only one message loop
127 for the main thread. If Initialize is called in a secondary thread,
128 the socket window will be created for the secondary thread, but
129 since there is no message loop on this thread, it will never
130 receive events and all socket operations will time out.
131 BTW, the main thread must not be stopped using sleep or block
132 on a semaphore (a bad idea in any case) or socket operations
135 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
136 the main thread. Because secondary threads do not have run loops,
137 adding event notifications to the "Current" loop would have no
138 effect at all, events would never fire.
140 wxASSERT_MSG( wxIsMainThread(),
141 "sockets must be initialized from the main thread" );
143 wxAppConsole
* const app
= wxAppConsole::GetInstance();
144 wxCHECK_RET( app
, "sockets can't be initialized without wxApp" );
146 ms_manager
= app
->GetTraits()->GetSocketManager();
149 // ==========================================================================
151 // ==========================================================================
153 // --------------------------------------------------------------------------
154 // Initialization and shutdown
155 // --------------------------------------------------------------------------
157 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
158 // to m_countInit with a crit section
159 size_t wxSocketBase::m_countInit
= 0;
161 bool wxSocketBase::IsInitialized()
163 return m_countInit
> 0;
166 bool wxSocketBase::Initialize()
168 if ( !m_countInit
++ )
170 if ( !GSocket_Init() )
181 void wxSocketBase::Shutdown()
183 // we should be initialized
184 wxASSERT_MSG( m_countInit
> 0, _T("extra call to Shutdown()") );
185 if ( --m_countInit
== 0 )
191 // --------------------------------------------------------------------------
193 // --------------------------------------------------------------------------
195 void wxSocketBase::Init()
198 m_type
= wxSOCKET_UNINIT
;
210 m_beingDeleted
= false;
224 if ( !IsInitialized() )
226 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
227 // other calls to it should be matched by a call to Shutdown()
232 wxSocketBase::wxSocketBase()
237 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
245 wxSocketBase::~wxSocketBase()
247 // Just in case the app called Destroy() *and* then deleted
248 // the socket immediately: don't leave dangling pointers.
249 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
251 traits
->RemoveFromPendingDelete(this);
253 // Shutdown and close the socket
257 // Destroy the GSocket object
261 // Free the pushback buffer
266 bool wxSocketBase::Destroy()
268 // Delayed destruction: the socket will be deleted during the next
269 // idle loop iteration. This ensures that all pending events have
271 m_beingDeleted
= true;
273 // Shutdown and close the socket
276 // Supress events from now on
279 // schedule this object for deletion
280 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
283 // let the traits object decide what to do with us
284 traits
->ScheduleForDestroy(this);
286 else // no app or no traits
288 // in wxBase we might have no app object at all, don't leak memory
295 // --------------------------------------------------------------------------
297 // --------------------------------------------------------------------------
299 // The following IO operations update m_error and m_lcount:
300 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
302 // TODO: Should Connect, Accept and AcceptWith update m_error?
304 bool wxSocketBase::Close()
306 // Interrupt pending waits
312 m_socket
->UnsetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
313 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
315 // Shutdown the connection
316 m_socket
->Shutdown();
320 m_establishing
= false;
324 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
329 m_lcount
= _Read(buffer
, nbytes
);
331 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
332 if (m_flags
& wxSOCKET_WAITALL
)
333 m_error
= (m_lcount
!= nbytes
);
335 m_error
= (m_lcount
== 0);
337 // Allow read events from now on
343 wxUint32
wxSocketBase::_Read(void* buffer_
, wxUint32 nbytes
)
345 char *buffer
= (char *)buffer_
;
349 // Try the pushback buffer first
350 total
= GetPushback(buffer
, nbytes
, false);
352 buffer
= (char *)buffer
+ total
;
354 // Return now in one of the following cases:
355 // - the socket is invalid,
356 // - we got all the data
361 // Possible combinations (they are checked in this order)
363 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
368 if (m_flags
& wxSOCKET_NOWAIT
)
370 m_socket
->SetNonBlocking(1);
371 ret
= m_socket
->Read(buffer
, nbytes
);
372 m_socket
->SetNonBlocking(0);
379 else // blocking socket
383 // dispatch events unless disabled
384 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
387 ret
= m_socket
->Read(buffer
, nbytes
);
390 // for connection-oriented (e.g. TCP) sockets we can only read 0
391 // bytes if the other end has been closed, and for connectionless
392 // ones (UDP) this flag doesn't make sense anyhow so we can set it to
393 // true too without doing any harm
400 // this will be always interpreted as error by Read()
406 // if wxSOCKET_WAITALL is not set, we can leave now as we did read
408 if ( !(m_flags
& wxSOCKET_WAITALL
) )
411 // otherwise check if read the maximal requested amount of data
416 // we didn't, so continue reading
417 buffer
= (char *)buffer
+ ret
;
424 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
426 wxUint32 len
, len2
, sig
, total
;
431 unsigned char sig
[4];
432 unsigned char len
[4];
441 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
443 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
446 sig
= (wxUint32
)msg
.sig
[0];
447 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
448 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
449 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
451 if (sig
!= 0xfeeddead)
453 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
457 len
= (wxUint32
)msg
.len
[0];
458 len
|= (wxUint32
)(msg
.len
[1] << 8);
459 len
|= (wxUint32
)(msg
.len
[2] << 16);
460 len
|= (wxUint32
)(msg
.len
[3] << 24);
470 // Don't attemp to read if the msg was zero bytes long.
473 total
= _Read(buffer
, len
);
480 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
483 // NOTE: discarded bytes don't add to m_lcount.
486 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
487 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
488 len2
-= (wxUint32
)discard_len
;
490 while ((discard_len
> 0) && len2
);
492 delete [] discard_buffer
;
497 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
500 sig
= (wxUint32
)msg
.sig
[0];
501 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
502 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
503 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
505 if (sig
!= 0xdeadfeed)
507 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
523 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
528 m_lcount
= _Read(buffer
, nbytes
);
529 Pushback(buffer
, m_lcount
);
531 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
532 if (m_flags
& wxSOCKET_WAITALL
)
533 m_error
= (m_lcount
!= nbytes
);
535 m_error
= (m_lcount
== 0);
537 // Allow read events again
543 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
548 m_lcount
= _Write(buffer
, nbytes
);
550 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
551 if (m_flags
& wxSOCKET_WAITALL
)
552 m_error
= (m_lcount
!= nbytes
);
554 m_error
= (m_lcount
== 0);
556 // Allow write events again
562 wxUint32
wxSocketBase::_Write(const void *buffer_
, wxUint32 nbytes
)
564 const char *buffer
= (const char *)buffer_
;
568 // If the socket is invalid or parameters are ill, return immediately
569 if (!m_socket
|| !buffer
|| !nbytes
)
572 // Possible combinations (they are checked in this order)
574 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
579 if (m_flags
& wxSOCKET_NOWAIT
)
581 m_socket
->SetNonBlocking(1);
582 ret
= m_socket
->Write(buffer
, nbytes
);
583 m_socket
->SetNonBlocking(0);
588 else // blocking socket
592 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
595 ret
= m_socket
->Write(buffer
, nbytes
);
597 // see comments for similar logic for ret handling in _Read()
610 if ( !(m_flags
& wxSOCKET_WAITALL
) )
617 buffer
= (const char *)buffer
+ ret
;
624 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
630 unsigned char sig
[4];
631 unsigned char len
[4];
639 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
641 msg
.sig
[0] = (unsigned char) 0xad;
642 msg
.sig
[1] = (unsigned char) 0xde;
643 msg
.sig
[2] = (unsigned char) 0xed;
644 msg
.sig
[3] = (unsigned char) 0xfe;
646 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
647 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
648 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
649 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
651 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
654 total
= _Write(buffer
, nbytes
);
659 msg
.sig
[0] = (unsigned char) 0xed;
660 msg
.sig
[1] = (unsigned char) 0xfe;
661 msg
.sig
[2] = (unsigned char) 0xad;
662 msg
.sig
[3] = (unsigned char) 0xde;
663 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
665 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
679 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
682 Pushback(buffer
, nbytes
);
690 wxSocketBase
& wxSocketBase::Discard()
692 char *buffer
= new char[MAX_DISCARD_SIZE
];
699 SetFlags(wxSOCKET_NOWAIT
);
703 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
706 while (ret
== MAX_DISCARD_SIZE
);
712 // Allow read events again
718 // --------------------------------------------------------------------------
720 // --------------------------------------------------------------------------
722 // All Wait functions poll the socket using GSocket_Select() to
723 // check for the specified combination of conditions, until one
724 // of these conditions become true, an error occurs, or the
725 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
726 // this won't block the GUI.
728 bool wxSocketBase::_Wait(long seconds
,
730 wxSocketEventFlags flags
)
732 GSocketEventFlags result
;
733 long timeout
; // in ms
735 // Set this to true to interrupt ongoing waits
738 // Check for valid socket
742 // Check for valid timeout value.
744 timeout
= seconds
* 1000 + milliseconds
;
746 timeout
= m_timeout
* 1000;
748 // check if we are using event loop or not: normally we do in GUI but not in
749 // console applications but this can be overridden
750 const bool has_event_loop
= wxEventLoop::GetActive() != NULL
;
752 // Wait in an active polling loop.
754 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
755 // hurt. It has to be here because the (GSocket) event might arrive
756 // a bit delayed, and it has to be in OnRequest as well because we
757 // don't know whether the Wait functions are being used.
759 // Do this at least once (important if timeout == 0, when
760 // we are just polling). Also, if just polling, do not yield.
762 const wxMilliClock_t time_limit
= wxGetLocalTimeMillis() + timeout
;
764 bool valid_result
= false;
768 // This is used to avoid a busy loop on wxBase - having a select
769 // timeout of 50 ms per iteration should be enough.
771 m_socket
->SetTimeout(50);
773 m_socket
->SetTimeout(timeout
);
778 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
780 // Incoming connection (server) or connection established (client)
781 if (result
& GSOCK_CONNECTION_FLAG
)
784 m_establishing
= false;
789 // Data available or output buffer ready
790 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
797 if (result
& GSOCK_LOST_FLAG
)
800 m_establishing
= false;
801 valid_result
= ((flags
& GSOCK_LOST_FLAG
) != 0);
806 long time_left
= wxMilliClockToLong(time_limit
- wxGetLocalTimeMillis());
807 if ((!timeout
) || (time_left
<= 0) || (m_interrupt
))
817 // If there's less than 50 ms left, just call select with that timeout.
819 m_socket
->SetTimeout(time_left
);
824 // Set timeout back to original value (we overwrote it for polling)
826 m_socket
->SetTimeout(m_timeout
*1000);
831 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
833 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
835 GSOCK_CONNECTION_FLAG
|
839 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
841 // Check pushback buffer before entering _Wait
845 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
846 // _Wait because of the semantics of WaitForRead: a return
847 // value of true means that a GSocket_Read call will return
848 // immediately, not that there is actually data to read.
850 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
855 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
857 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
860 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
862 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
865 // --------------------------------------------------------------------------
867 // --------------------------------------------------------------------------
870 // Get local or peer address
873 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
880 peer
= m_socket
->GetPeer();
882 // copying a null address would just trigger an assert anyway
887 addr_man
.SetAddress(peer
);
888 GAddress_destroy(peer
);
893 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
900 local
= m_socket
->GetLocal();
901 addr_man
.SetAddress(local
);
902 GAddress_destroy(local
);
908 // Save and restore socket state
911 void wxSocketBase::SaveState()
913 wxSocketState
*state
;
915 state
= new wxSocketState();
917 state
->m_flags
= m_flags
;
918 state
->m_notify
= m_notify
;
919 state
->m_eventmask
= m_eventmask
;
920 state
->m_clientData
= m_clientData
;
922 m_states
.Append(state
);
925 void wxSocketBase::RestoreState()
927 wxList::compatibility_iterator node
;
928 wxSocketState
*state
;
930 node
= m_states
.GetLast();
934 state
= (wxSocketState
*)node
->GetData();
936 m_flags
= state
->m_flags
;
937 m_notify
= state
->m_notify
;
938 m_eventmask
= state
->m_eventmask
;
939 m_clientData
= state
->m_clientData
;
941 m_states
.Erase(node
);
949 void wxSocketBase::SetTimeout(long seconds
)
954 m_socket
->SetTimeout(m_timeout
* 1000);
957 void wxSocketBase::SetFlags(wxSocketFlags flags
)
963 // --------------------------------------------------------------------------
965 // --------------------------------------------------------------------------
967 // A note on how events are processed, which is probably the most
968 // difficult thing to get working right while keeping the same API
969 // and functionality for all platforms.
971 // When GSocket detects an event, it calls wx_socket_callback, which in
972 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
973 // object. OnRequest does some housekeeping, and if the event is to be
974 // propagated to the user, it creates a new wxSocketEvent object and
975 // posts it. The event is not processed immediately, but delayed with
976 // AddPendingEvent instead. This is necessary in order to decouple the
977 // event processing from wx_socket_callback; otherwise, subsequent IO
978 // calls made from the user event handler would fail, as gtk callbacks
979 // are not reentrant.
981 // Note that, unlike events, user callbacks (now deprecated) are _not_
982 // decoupled from wx_socket_callback and thus they suffer from a variety
983 // of problems. Avoid them where possible and use events instead.
986 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
987 GSocketEvent notification
,
990 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
992 sckobj
->OnRequest((wxSocketNotify
) notification
);
995 void wxSocketBase::OnRequest(wxSocketNotify notification
)
997 // NOTE: We duplicate some of the code in _Wait, but this doesn't
998 // hurt. It has to be here because the (GSocket) event might arrive
999 // a bit delayed, and it has to be in _Wait as well because we don't
1000 // know whether the Wait functions are being used.
1002 switch(notification
)
1004 case wxSOCKET_CONNECTION
:
1005 m_establishing
= false;
1009 // If we are in the middle of a R/W operation, do not
1010 // propagate events to users. Also, filter 'late' events
1011 // which are no longer valid.
1013 case wxSOCKET_INPUT
:
1014 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
1018 case wxSOCKET_OUTPUT
:
1019 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
1024 m_connected
= false;
1025 m_establishing
= false;
1032 // Schedule the event
1034 wxSocketEventFlags flag
= 0;
1036 switch (notification
)
1038 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
1039 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
1040 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
1041 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
1043 wxLogWarning(_("wxSocket: unknown event!."));
1047 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1051 wxSocketEvent
event(m_id
);
1052 event
.m_event
= notification
;
1053 event
.m_clientData
= m_clientData
;
1054 event
.SetEventObject(this);
1056 m_handler
->AddPendingEvent(event
);
1061 void wxSocketBase::Notify(bool notify
)
1065 m_socket
->Notify(notify
);
1068 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1070 m_eventmask
= flags
;
1073 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1075 m_handler
= &handler
;
1079 // --------------------------------------------------------------------------
1081 // --------------------------------------------------------------------------
1083 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1087 if (m_unread
== NULL
)
1088 m_unread
= malloc(size
);
1093 tmp
= malloc(m_unrd_size
+ size
);
1094 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1100 m_unrd_size
+= size
;
1102 memcpy(m_unread
, buffer
, size
);
1105 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1110 if (size
> (m_unrd_size
-m_unrd_cur
))
1111 size
= m_unrd_size
-m_unrd_cur
;
1113 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1118 if (m_unrd_size
== m_unrd_cur
)
1131 // ==========================================================================
1133 // ==========================================================================
1135 // --------------------------------------------------------------------------
1137 // --------------------------------------------------------------------------
1139 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1140 wxSocketFlags flags
)
1141 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1143 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1145 m_socket
= GSocket_new();
1149 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1153 // Setup the socket as server
1154 m_socket
->Notify(m_notify
);
1155 m_socket
->SetLocal(addr_man
.GetAddress());
1157 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1158 m_socket
->SetReusable();
1160 if (GetFlags() & wxSOCKET_BROADCAST
) {
1161 m_socket
->SetBroadcast();
1163 if (GetFlags() & wxSOCKET_NOBIND
) {
1164 m_socket
->DontDoBind();
1167 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1172 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1176 m_socket
->SetTimeout(m_timeout
* 1000);
1177 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1178 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1179 wx_socket_callback
, (char *)this);
1181 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_socket
->m_fd
);
1184 // --------------------------------------------------------------------------
1186 // --------------------------------------------------------------------------
1188 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1190 GSocket
*child_socket
;
1195 // If wait == false, then the call should be nonblocking.
1196 // When we are finished, we put the socket to blocking mode
1200 m_socket
->SetNonBlocking(1);
1202 child_socket
= m_socket
->WaitConnection();
1205 m_socket
->SetNonBlocking(0);
1210 sock
.m_type
= wxSOCKET_BASE
;
1211 sock
.m_socket
= child_socket
;
1212 sock
.m_connected
= true;
1214 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1215 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1216 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1217 wx_socket_callback
, (char *)&sock
);
1222 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1224 wxSocketBase
* sock
= new wxSocketBase();
1226 sock
->SetFlags(m_flags
);
1228 if (!AcceptWith(*sock
, wait
))
1237 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1239 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1242 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1244 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1246 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1254 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1257 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1259 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1267 bool wxSocketBase::SetLocal(const wxIPV4address
& local
)
1269 GAddress
* la
= local
.GetAddress();
1271 // If the address is valid, save it for use when we call Connect
1272 if (la
&& la
->m_addr
)
1274 m_localAddress
= local
;
1282 // ==========================================================================
1284 // ==========================================================================
1286 // --------------------------------------------------------------------------
1288 // --------------------------------------------------------------------------
1290 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1291 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1293 m_initialRecvBufferSize
=
1294 m_initialSendBufferSize
= -1;
1297 wxSocketClient::~wxSocketClient()
1301 // --------------------------------------------------------------------------
1303 // --------------------------------------------------------------------------
1305 bool wxSocketClient::DoConnect(const wxSockAddress
& addr_man
,
1306 const wxSockAddress
* local
,
1313 // Shutdown and destroy the socket
1318 m_socket
= GSocket_new();
1319 m_connected
= false;
1320 m_establishing
= false;
1325 m_socket
->SetTimeout(m_timeout
* 1000);
1326 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1327 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1328 wx_socket_callback
, (char *)this);
1330 // If wait == false, then the call should be nonblocking.
1331 // When we are finished, we put the socket to blocking mode
1335 m_socket
->SetNonBlocking(1);
1337 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1338 if (GetFlags() & wxSOCKET_REUSEADDR
)
1340 m_socket
->SetReusable();
1342 if (GetFlags() & wxSOCKET_BROADCAST
)
1344 m_socket
->SetBroadcast();
1346 if (GetFlags() & wxSOCKET_NOBIND
)
1348 m_socket
->DontDoBind();
1351 // If no local address was passed and one has been set, use the one that was Set
1352 if (!local
&& m_localAddress
.GetAddress())
1354 local
= &m_localAddress
;
1357 // Bind to the local IP address and port, when provided
1360 GAddress
* la
= local
->GetAddress();
1362 if (la
&& la
->m_addr
)
1363 m_socket
->SetLocal(la
);
1366 #if defined(__WXMSW__) || defined(__WXGTK__)
1367 m_socket
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1370 m_socket
->SetPeer(addr_man
.GetAddress());
1371 err
= m_socket
->Connect(GSOCK_STREAMED
);
1373 //this will register for callbacks - must be called after m_socket->m_fd was initialized
1374 m_socket
->Notify(m_notify
);
1377 m_socket
->SetNonBlocking(0);
1379 if (err
!= GSOCK_NOERROR
)
1381 if (err
== GSOCK_WOULDBLOCK
)
1382 m_establishing
= true;
1391 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
, bool wait
)
1393 return DoConnect(addr_man
, NULL
, wait
);
1396 bool wxSocketClient::Connect(const wxSockAddress
& addr_man
,
1397 const wxSockAddress
& local
,
1400 return DoConnect(addr_man
, &local
, wait
);
1403 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1405 if (m_connected
) // Already connected
1408 if (!m_establishing
|| !m_socket
) // No connection in progress
1411 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1415 // ==========================================================================
1417 // ==========================================================================
1419 /* NOTE: experimental stuff - might change */
1421 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1422 wxSocketFlags flags
)
1423 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1425 // Create the socket
1426 m_socket
= GSocket_new();
1430 wxFAIL_MSG( _T("datagram socket not new'd") );
1433 m_socket
->Notify(m_notify
);
1434 // Setup the socket as non connection oriented
1435 m_socket
->SetLocal(addr
.GetAddress());
1436 if (flags
& wxSOCKET_REUSEADDR
)
1438 m_socket
->SetReusable();
1440 if (GetFlags() & wxSOCKET_BROADCAST
)
1442 m_socket
->SetBroadcast();
1444 if (GetFlags() & wxSOCKET_NOBIND
)
1446 m_socket
->DontDoBind();
1448 if ( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1455 // Initialize all stuff
1456 m_connected
= false;
1457 m_establishing
= false;
1458 m_socket
->SetTimeout( m_timeout
);
1459 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1460 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1461 wx_socket_callback
, (char*)this );
1464 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1473 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1477 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1479 m_socket
->SetPeer(addr
.GetAddress());
1484 // ==========================================================================
1486 // ==========================================================================
1488 class wxSocketModule
: public wxModule
1491 virtual bool OnInit()
1493 // wxSocketBase will call GSocket_Init() itself when/if needed
1497 virtual void OnExit()
1499 if ( wxSocketBase::IsInitialized() )
1500 wxSocketBase::Shutdown();
1504 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1507 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)