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"
41 #include "wx/sckaddr.h"
42 #include "wx/datetime.h"
44 // DLL options compatibility check:
46 WX_CHECK_BUILD_OPTIONS("wxNet")
48 // --------------------------------------------------------------------------
49 // macros and constants
50 // --------------------------------------------------------------------------
53 #define MAX_DISCARD_SIZE (10 * 1024)
55 // what to do within waits: we have 2 cases: from the main thread itself we
56 // have to call wxYield() to let the events (including the GUI events and the
57 // low-level (not wxWidgets) events from GSocket) be processed. From another
58 // thread it is enough to just call wxThread::Yield() which will give away the
59 // rest of our time slice: the explanation is that the events will be processed
60 // by the main thread anyhow, without calling wxYield(), but we don't want to
61 // eat the CPU time uselessly while sitting in the loop waiting for the data
63 #define PROCESS_EVENTS() \
65 if ( wxThread::IsMain() ) \
70 #else // !wxUSE_THREADS
71 #define PROCESS_EVENTS() wxYield()
72 #endif // wxUSE_THREADS/!wxUSE_THREADS
74 #define wxTRACE_Socket _T("wxSocket")
76 // --------------------------------------------------------------------------
78 // --------------------------------------------------------------------------
80 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
81 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
82 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
83 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
84 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
86 // --------------------------------------------------------------------------
88 // --------------------------------------------------------------------------
90 class wxSocketState
: public wxObject
93 wxSocketFlags m_flags
;
94 wxSocketEventFlags m_eventmask
;
99 wxSocketState() : wxObject() {}
101 DECLARE_NO_COPY_CLASS(wxSocketState
)
104 // ==========================================================================
106 // ==========================================================================
108 // --------------------------------------------------------------------------
109 // Initialization and shutdown
110 // --------------------------------------------------------------------------
112 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
113 // to m_countInit with a crit section
114 size_t wxSocketBase::m_countInit
= 0;
116 bool wxSocketBase::IsInitialized()
118 return m_countInit
> 0;
121 bool wxSocketBase::Initialize()
123 if ( !m_countInit
++ )
126 Details: Initialize() creates a hidden window as a sink for socket
127 events, such as 'read completed'. wxMSW has only one message loop
128 for the main thread. If Initialize is called in a secondary thread,
129 the socket window will be created for the secondary thread, but
130 since there is no message loop on this thread, it will never
131 receive events and all socket operations will time out.
132 BTW, the main thread must not be stopped using sleep or block
133 on a semaphore (a bad idea in any case) or socket operations
136 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
137 the main thread. Because secondary threads do not have run loops,
138 adding event notifications to the "Current" loop would have no
139 effect at all, events would never fire.
141 wxASSERT_MSG( wxIsMainThread(),
142 wxT("Call wxSocketBase::Initialize() from the main thread first!"));
144 wxAppTraits
*traits
= wxAppConsole::GetInstance() ?
145 wxAppConsole::GetInstance()->GetTraits() : NULL
;
146 GSocketGUIFunctionsTable
*functions
=
147 traits
? traits
->GetSocketGUIFunctionsTable() : NULL
;
148 GSocket_SetGUIFunctions(functions
);
150 if ( !GSocket_Init() )
161 void wxSocketBase::Shutdown()
163 // we should be initialized
164 wxASSERT_MSG( m_countInit
, _T("extra call to Shutdown()") );
165 if ( --m_countInit
== 0 )
171 // --------------------------------------------------------------------------
173 // --------------------------------------------------------------------------
175 void wxSocketBase::Init()
178 m_type
= wxSOCKET_UNINIT
;
189 m_beingDeleted
= false;
203 if ( !IsInitialized() )
205 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
206 // other calls to it should be matched by a call to Shutdown()
211 wxSocketBase::wxSocketBase()
216 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
224 wxSocketBase::~wxSocketBase()
226 // Just in case the app called Destroy() *and* then deleted
227 // the socket immediately: don't leave dangling pointers.
228 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
230 traits
->RemoveFromPendingDelete(this);
232 // Shutdown and close the socket
236 // Destroy the GSocket object
240 // Free the pushback buffer
245 bool wxSocketBase::Destroy()
247 // Delayed destruction: the socket will be deleted during the next
248 // idle loop iteration. This ensures that all pending events have
250 m_beingDeleted
= true;
252 // Shutdown and close the socket
255 // Supress events from now on
258 // schedule this object for deletion
259 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
262 // let the traits object decide what to do with us
263 traits
->ScheduleForDestroy(this);
265 else // no app or no traits
267 // in wxBase we might have no app object at all, don't leak memory
274 // --------------------------------------------------------------------------
276 // --------------------------------------------------------------------------
278 // The following IO operations update m_error and m_lcount:
279 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
281 // TODO: Should Connect, Accept and AcceptWith update m_error?
283 bool wxSocketBase::Close()
285 // Interrupt pending waits
291 m_socket
->UnsetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
292 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
294 // Shutdown the connection
295 m_socket
->Shutdown();
299 m_establishing
= false;
303 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
308 m_lcount
= _Read(buffer
, nbytes
);
310 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
311 if (m_flags
& wxSOCKET_WAITALL
)
312 m_error
= (m_lcount
!= nbytes
);
314 m_error
= (m_lcount
== 0);
316 // Allow read events from now on
322 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
326 // Try the pushback buffer first
327 total
= GetPushback(buffer
, nbytes
, false);
329 buffer
= (char *)buffer
+ total
;
331 // Return now in one of the following cases:
332 // - the socket is invalid,
333 // - we got all the data
338 // Possible combinations (they are checked in this order)
340 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
345 if (m_flags
& wxSOCKET_NOWAIT
)
347 m_socket
->SetNonBlocking(1);
348 ret
= m_socket
->Read((char *)buffer
, nbytes
);
349 m_socket
->SetNonBlocking(0);
360 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
363 ret
= m_socket
->Read((char *)buffer
, nbytes
);
369 buffer
= (char *)buffer
+ ret
;
372 // If we got here and wxSOCKET_WAITALL is not set, we can leave
373 // now. Otherwise, wait until we recv all the data or until there
376 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
383 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
385 wxUint32 len
, len2
, sig
, total
;
390 unsigned char sig
[4];
391 unsigned char len
[4];
400 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
402 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
405 sig
= (wxUint32
)msg
.sig
[0];
406 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
407 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
408 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
410 if (sig
!= 0xfeeddead)
412 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
416 len
= (wxUint32
)msg
.len
[0];
417 len
|= (wxUint32
)(msg
.len
[1] << 8);
418 len
|= (wxUint32
)(msg
.len
[2] << 16);
419 len
|= (wxUint32
)(msg
.len
[3] << 24);
429 // Don't attemp to read if the msg was zero bytes long.
432 total
= _Read(buffer
, len
);
439 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
442 // NOTE: discarded bytes don't add to m_lcount.
445 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
446 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
447 len2
-= (wxUint32
)discard_len
;
449 while ((discard_len
> 0) && len2
);
451 delete [] discard_buffer
;
456 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
459 sig
= (wxUint32
)msg
.sig
[0];
460 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
461 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
462 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
464 if (sig
!= 0xdeadfeed)
466 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
482 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
487 m_lcount
= _Read(buffer
, nbytes
);
488 Pushback(buffer
, m_lcount
);
490 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
491 if (m_flags
& wxSOCKET_WAITALL
)
492 m_error
= (m_lcount
!= nbytes
);
494 m_error
= (m_lcount
== 0);
496 // Allow read events again
502 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
507 m_lcount
= _Write(buffer
, nbytes
);
509 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
510 if (m_flags
& wxSOCKET_WAITALL
)
511 m_error
= (m_lcount
!= nbytes
);
513 m_error
= (m_lcount
== 0);
515 // Allow write events again
521 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
525 // If the socket is invalid or parameters are ill, return immediately
526 if (!m_socket
|| !buffer
|| !nbytes
)
529 // Possible combinations (they are checked in this order)
531 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
536 if (m_flags
& wxSOCKET_NOWAIT
)
538 m_socket
->SetNonBlocking(1);
539 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
540 m_socket
->SetNonBlocking(0);
551 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
554 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
560 buffer
= (const char *)buffer
+ ret
;
563 // If we got here and wxSOCKET_WAITALL is not set, we can leave
564 // now. Otherwise, wait until we send all the data or until there
567 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
574 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
580 unsigned char sig
[4];
581 unsigned char len
[4];
589 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
591 msg
.sig
[0] = (unsigned char) 0xad;
592 msg
.sig
[1] = (unsigned char) 0xde;
593 msg
.sig
[2] = (unsigned char) 0xed;
594 msg
.sig
[3] = (unsigned char) 0xfe;
596 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
597 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
598 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
599 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
601 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
604 total
= _Write(buffer
, nbytes
);
609 msg
.sig
[0] = (unsigned char) 0xed;
610 msg
.sig
[1] = (unsigned char) 0xfe;
611 msg
.sig
[2] = (unsigned char) 0xad;
612 msg
.sig
[3] = (unsigned char) 0xde;
613 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
615 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
629 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
632 Pushback(buffer
, nbytes
);
640 wxSocketBase
& wxSocketBase::Discard()
642 char *buffer
= new char[MAX_DISCARD_SIZE
];
649 SetFlags(wxSOCKET_NOWAIT
);
653 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
656 while (ret
== MAX_DISCARD_SIZE
);
662 // Allow read events again
668 // --------------------------------------------------------------------------
670 // --------------------------------------------------------------------------
672 // All Wait functions poll the socket using GSocket_Select() to
673 // check for the specified combination of conditions, until one
674 // of these conditions become true, an error occurs, or the
675 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
676 // this won't block the GUI.
678 bool wxSocketBase::_Wait(long seconds
,
680 wxSocketEventFlags flags
)
682 GSocketEventFlags result
;
685 // Set this to true to interrupt ongoing waits
688 // Check for valid socket
692 // Check for valid timeout value.
694 timeout
= seconds
* 1000 + milliseconds
;
696 timeout
= m_timeout
* 1000;
698 bool has_event_loop
= wxTheApp
->GetTraits() ? (wxTheApp
->GetTraits()->GetSocketGUIFunctionsTable() ? true : false) : false;
700 // Wait in an active polling loop.
702 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
703 // hurt. It has to be here because the (GSocket) event might arrive
704 // a bit delayed, and it has to be in OnRequest as well because we
705 // don't know whether the Wait functions are being used.
707 // Do this at least once (important if timeout == 0, when
708 // we are just polling). Also, if just polling, do not yield.
710 wxDateTime current_time
= wxDateTime::UNow();
711 unsigned int time_limit
= (current_time
.GetTicks() * 1000) + current_time
.GetMillisecond() + timeout
;
713 bool valid_result
= false;
717 // This is used to avoid a busy loop on wxBase - having a select
718 // timeout of 50 ms per iteration should be enough.
720 m_socket
->SetTimeout(50);
722 m_socket
->SetTimeout(timeout
);
727 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
729 // Incoming connection (server) or connection established (client)
730 if (result
& GSOCK_CONNECTION_FLAG
)
733 m_establishing
= false;
738 // Data available or output buffer ready
739 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
746 if (result
& GSOCK_LOST_FLAG
)
749 m_establishing
= false;
750 valid_result
= ((flags
& GSOCK_LOST_FLAG
) != 0);
755 current_time
= wxDateTime::UNow();
756 int time_left
= time_limit
- ((current_time
.GetTicks() * 1000) + current_time
.GetMillisecond());
757 if ((!timeout
) || (time_left
<= 0) || (m_interrupt
))
767 // If there's less than 50 ms left, just call select with that timeout.
769 m_socket
->SetTimeout(time_left
);
774 // Set timeout back to original value (we overwrote it for polling)
776 m_socket
->SetTimeout(m_timeout
*1000);
781 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
783 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
785 GSOCK_CONNECTION_FLAG
|
789 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
791 // Check pushback buffer before entering _Wait
795 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
796 // _Wait because of the semantics of WaitForRead: a return
797 // value of true means that a GSocket_Read call will return
798 // immediately, not that there is actually data to read.
800 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
805 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
807 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
810 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
812 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
815 // --------------------------------------------------------------------------
817 // --------------------------------------------------------------------------
820 // Get local or peer address
823 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
830 peer
= m_socket
->GetPeer();
832 // copying a null address would just trigger an assert anyway
837 addr_man
.SetAddress(peer
);
838 GAddress_destroy(peer
);
843 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
850 local
= m_socket
->GetLocal();
851 addr_man
.SetAddress(local
);
852 GAddress_destroy(local
);
858 // Save and restore socket state
861 void wxSocketBase::SaveState()
863 wxSocketState
*state
;
865 state
= new wxSocketState();
867 state
->m_flags
= m_flags
;
868 state
->m_notify
= m_notify
;
869 state
->m_eventmask
= m_eventmask
;
870 state
->m_clientData
= m_clientData
;
872 m_states
.Append(state
);
875 void wxSocketBase::RestoreState()
877 wxList::compatibility_iterator node
;
878 wxSocketState
*state
;
880 node
= m_states
.GetLast();
884 state
= (wxSocketState
*)node
->GetData();
886 m_flags
= state
->m_flags
;
887 m_notify
= state
->m_notify
;
888 m_eventmask
= state
->m_eventmask
;
889 m_clientData
= state
->m_clientData
;
891 m_states
.Erase(node
);
899 void wxSocketBase::SetTimeout(long seconds
)
904 m_socket
->SetTimeout(m_timeout
* 1000);
907 void wxSocketBase::SetFlags(wxSocketFlags flags
)
913 // --------------------------------------------------------------------------
915 // --------------------------------------------------------------------------
917 // A note on how events are processed, which is probably the most
918 // difficult thing to get working right while keeping the same API
919 // and functionality for all platforms.
921 // When GSocket detects an event, it calls wx_socket_callback, which in
922 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
923 // object. OnRequest does some housekeeping, and if the event is to be
924 // propagated to the user, it creates a new wxSocketEvent object and
925 // posts it. The event is not processed immediately, but delayed with
926 // AddPendingEvent instead. This is necessary in order to decouple the
927 // event processing from wx_socket_callback; otherwise, subsequent IO
928 // calls made from the user event handler would fail, as gtk callbacks
929 // are not reentrant.
931 // Note that, unlike events, user callbacks (now deprecated) are _not_
932 // decoupled from wx_socket_callback and thus they suffer from a variety
933 // of problems. Avoid them where possible and use events instead.
936 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
937 GSocketEvent notification
,
940 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
942 sckobj
->OnRequest((wxSocketNotify
) notification
);
945 void wxSocketBase::OnRequest(wxSocketNotify notification
)
947 // NOTE: We duplicate some of the code in _Wait, but this doesn't
948 // hurt. It has to be here because the (GSocket) event might arrive
949 // a bit delayed, and it has to be in _Wait as well because we don't
950 // know whether the Wait functions are being used.
954 case wxSOCKET_CONNECTION
:
955 m_establishing
= false;
959 // If we are in the middle of a R/W operation, do not
960 // propagate events to users. Also, filter 'late' events
961 // which are no longer valid.
964 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
968 case wxSOCKET_OUTPUT
:
969 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
975 m_establishing
= false;
982 // Schedule the event
984 wxSocketEventFlags flag
= 0;
986 switch (notification
)
988 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
989 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
990 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
991 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
993 wxLogWarning(_("wxSocket: unknown event!."));
997 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1001 wxSocketEvent
event(m_id
);
1002 event
.m_event
= notification
;
1003 event
.m_clientData
= m_clientData
;
1004 event
.SetEventObject(this);
1006 m_handler
->AddPendingEvent(event
);
1011 void wxSocketBase::Notify(bool notify
)
1016 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1018 m_eventmask
= flags
;
1021 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1023 m_handler
= &handler
;
1027 // --------------------------------------------------------------------------
1029 // --------------------------------------------------------------------------
1031 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1035 if (m_unread
== NULL
)
1036 m_unread
= malloc(size
);
1041 tmp
= malloc(m_unrd_size
+ size
);
1042 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1048 m_unrd_size
+= size
;
1050 memcpy(m_unread
, buffer
, size
);
1053 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1058 if (size
> (m_unrd_size
-m_unrd_cur
))
1059 size
= m_unrd_size
-m_unrd_cur
;
1061 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1066 if (m_unrd_size
== m_unrd_cur
)
1079 // ==========================================================================
1081 // ==========================================================================
1083 // --------------------------------------------------------------------------
1085 // --------------------------------------------------------------------------
1087 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1088 wxSocketFlags flags
)
1089 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1091 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1093 m_socket
= GSocket_new();
1097 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1101 // Setup the socket as server
1103 m_socket
->SetLocal(addr_man
.GetAddress());
1105 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1106 m_socket
->SetReusable();
1108 if (GetFlags() & wxSOCKET_BROADCAST
) {
1109 m_socket
->SetBroadcast();
1111 if (GetFlags() & wxSOCKET_NOBIND
) {
1112 m_socket
->DontDoBind();
1115 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1120 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1124 m_socket
->SetTimeout(m_timeout
* 1000);
1125 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1126 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1127 wx_socket_callback
, (char *)this);
1130 // --------------------------------------------------------------------------
1132 // --------------------------------------------------------------------------
1134 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1136 GSocket
*child_socket
;
1141 // If wait == false, then the call should be nonblocking.
1142 // When we are finished, we put the socket to blocking mode
1146 m_socket
->SetNonBlocking(1);
1148 child_socket
= m_socket
->WaitConnection();
1151 m_socket
->SetNonBlocking(0);
1156 sock
.m_type
= wxSOCKET_BASE
;
1157 sock
.m_socket
= child_socket
;
1158 sock
.m_connected
= true;
1160 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1161 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1162 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1163 wx_socket_callback
, (char *)&sock
);
1168 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1170 wxSocketBase
* sock
= new wxSocketBase();
1172 sock
->SetFlags(m_flags
);
1174 if (!AcceptWith(*sock
, wait
))
1183 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1185 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1188 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1190 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1192 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1200 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1203 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1205 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1213 bool wxSocketBase::SetLocal(wxIPV4address
& local
)
1215 GAddress
* la
= local
.GetAddress();
1217 // If the address is valid, save it for use when we call Connect
1218 if (la
&& la
->m_addr
)
1220 m_localAddress
= local
;
1228 // ==========================================================================
1230 // ==========================================================================
1232 // --------------------------------------------------------------------------
1234 // --------------------------------------------------------------------------
1236 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1237 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1241 wxSocketClient::~wxSocketClient()
1245 // --------------------------------------------------------------------------
1247 // --------------------------------------------------------------------------
1249 bool wxSocketClient::DoConnect(wxSockAddress
& addr_man
, wxSockAddress
* local
, bool wait
)
1255 // Shutdown and destroy the socket
1260 m_socket
= GSocket_new();
1261 m_connected
= false;
1262 m_establishing
= false;
1267 m_socket
->SetTimeout(m_timeout
* 1000);
1268 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1269 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1270 wx_socket_callback
, (char *)this);
1272 // If wait == false, then the call should be nonblocking.
1273 // When we are finished, we put the socket to blocking mode
1277 m_socket
->SetNonBlocking(1);
1279 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1280 if (GetFlags() & wxSOCKET_REUSEADDR
)
1282 m_socket
->SetReusable();
1284 if (GetFlags() & wxSOCKET_BROADCAST
)
1286 m_socket
->SetBroadcast();
1288 if (GetFlags() & wxSOCKET_NOBIND
)
1290 m_socket
->DontDoBind();
1293 // If no local address was passed and one has been set, use the one that was Set
1294 if (!local
&& m_localAddress
.GetAddress())
1296 local
= &m_localAddress
;
1299 // Bind to the local IP address and port, when provided
1302 GAddress
* la
= local
->GetAddress();
1304 if (la
&& la
->m_addr
)
1305 m_socket
->SetLocal(la
);
1308 m_socket
->SetPeer(addr_man
.GetAddress());
1309 err
= m_socket
->Connect(GSOCK_STREAMED
);
1312 m_socket
->SetNonBlocking(0);
1314 if (err
!= GSOCK_NOERROR
)
1316 if (err
== GSOCK_WOULDBLOCK
)
1317 m_establishing
= true;
1326 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1328 return (DoConnect(addr_man
, NULL
, wait
));
1331 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, wxSockAddress
& local
, bool wait
)
1333 return (DoConnect(addr_man
, &local
, wait
));
1336 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1338 if (m_connected
) // Already connected
1341 if (!m_establishing
|| !m_socket
) // No connection in progress
1344 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1348 // ==========================================================================
1350 // ==========================================================================
1352 /* NOTE: experimental stuff - might change */
1354 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1355 wxSocketFlags flags
)
1356 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1358 // Create the socket
1359 m_socket
= GSocket_new();
1363 wxFAIL_MSG( _T("datagram socket not new'd") );
1366 // Setup the socket as non connection oriented
1367 m_socket
->SetLocal(addr
.GetAddress());
1368 if (flags
& wxSOCKET_REUSEADDR
)
1370 m_socket
->SetReusable();
1372 if (GetFlags() & wxSOCKET_BROADCAST
)
1374 m_socket
->SetBroadcast();
1376 if (GetFlags() & wxSOCKET_NOBIND
)
1378 m_socket
->DontDoBind();
1380 if ( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1387 // Initialize all stuff
1388 m_connected
= false;
1389 m_establishing
= false;
1390 m_socket
->SetTimeout( m_timeout
);
1391 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1392 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1393 wx_socket_callback
, (char*)this );
1396 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1405 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1409 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1411 m_socket
->SetPeer(addr
.GetAddress());
1416 // ==========================================================================
1418 // ==========================================================================
1420 class wxSocketModule
: public wxModule
1423 virtual bool OnInit()
1425 // wxSocketBase will call GSocket_Init() itself when/if needed
1429 virtual void OnExit()
1431 if ( wxSocketBase::IsInitialized() )
1432 wxSocketBase::Shutdown();
1436 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1439 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)