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
;
209 m_beingDeleted
= false;
223 if ( !IsInitialized() )
225 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
226 // other calls to it should be matched by a call to Shutdown()
231 wxSocketBase::wxSocketBase()
236 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
244 wxSocketBase::~wxSocketBase()
246 // Just in case the app called Destroy() *and* then deleted
247 // the socket immediately: don't leave dangling pointers.
248 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
250 traits
->RemoveFromPendingDelete(this);
252 // Shutdown and close the socket
256 // Destroy the GSocket object
260 // Free the pushback buffer
265 bool wxSocketBase::Destroy()
267 // Delayed destruction: the socket will be deleted during the next
268 // idle loop iteration. This ensures that all pending events have
270 m_beingDeleted
= true;
272 // Shutdown and close the socket
275 // Supress events from now on
278 // schedule this object for deletion
279 wxAppTraits
*traits
= wxTheApp
? wxTheApp
->GetTraits() : NULL
;
282 // let the traits object decide what to do with us
283 traits
->ScheduleForDestroy(this);
285 else // no app or no traits
287 // in wxBase we might have no app object at all, don't leak memory
294 // --------------------------------------------------------------------------
296 // --------------------------------------------------------------------------
298 // The following IO operations update m_error and m_lcount:
299 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
301 // TODO: Should Connect, Accept and AcceptWith update m_error?
303 bool wxSocketBase::Close()
305 // Interrupt pending waits
311 m_socket
->UnsetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
312 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
314 // Shutdown the connection
315 m_socket
->Shutdown();
319 m_establishing
= false;
323 wxSocketBase
& wxSocketBase::Read(void* buffer
, wxUint32 nbytes
)
328 m_lcount
= _Read(buffer
, nbytes
);
330 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
331 if (m_flags
& wxSOCKET_WAITALL
)
332 m_error
= (m_lcount
!= nbytes
);
334 m_error
= (m_lcount
== 0);
336 // Allow read events from now on
342 wxUint32
wxSocketBase::_Read(void* buffer
, wxUint32 nbytes
)
346 // Try the pushback buffer first
347 total
= GetPushback(buffer
, nbytes
, false);
349 buffer
= (char *)buffer
+ total
;
351 // Return now in one of the following cases:
352 // - the socket is invalid,
353 // - we got all the data
358 // Possible combinations (they are checked in this order)
360 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
365 if (m_flags
& wxSOCKET_NOWAIT
)
367 m_socket
->SetNonBlocking(1);
368 ret
= m_socket
->Read((char *)buffer
, nbytes
);
369 m_socket
->SetNonBlocking(0);
380 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead() )
383 ret
= m_socket
->Read((char *)buffer
, nbytes
);
389 buffer
= (char *)buffer
+ ret
;
392 // If we got here and wxSOCKET_WAITALL is not set, we can leave
393 // now. Otherwise, wait until we recv all the data or until there
396 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
403 wxSocketBase
& wxSocketBase::ReadMsg(void* buffer
, wxUint32 nbytes
)
405 wxUint32 len
, len2
, sig
, total
;
410 unsigned char sig
[4];
411 unsigned char len
[4];
420 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
422 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
425 sig
= (wxUint32
)msg
.sig
[0];
426 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
427 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
428 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
430 if (sig
!= 0xfeeddead)
432 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
436 len
= (wxUint32
)msg
.len
[0];
437 len
|= (wxUint32
)(msg
.len
[1] << 8);
438 len
|= (wxUint32
)(msg
.len
[2] << 16);
439 len
|= (wxUint32
)(msg
.len
[3] << 24);
449 // Don't attemp to read if the msg was zero bytes long.
452 total
= _Read(buffer
, len
);
459 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
462 // NOTE: discarded bytes don't add to m_lcount.
465 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
466 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
467 len2
-= (wxUint32
)discard_len
;
469 while ((discard_len
> 0) && len2
);
471 delete [] discard_buffer
;
476 if (_Read(&msg
, sizeof(msg
)) != sizeof(msg
))
479 sig
= (wxUint32
)msg
.sig
[0];
480 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
481 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
482 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
484 if (sig
!= 0xdeadfeed)
486 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
502 wxSocketBase
& wxSocketBase::Peek(void* buffer
, wxUint32 nbytes
)
507 m_lcount
= _Read(buffer
, nbytes
);
508 Pushback(buffer
, m_lcount
);
510 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
511 if (m_flags
& wxSOCKET_WAITALL
)
512 m_error
= (m_lcount
!= nbytes
);
514 m_error
= (m_lcount
== 0);
516 // Allow read events again
522 wxSocketBase
& wxSocketBase::Write(const void *buffer
, wxUint32 nbytes
)
527 m_lcount
= _Write(buffer
, nbytes
);
529 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
530 if (m_flags
& wxSOCKET_WAITALL
)
531 m_error
= (m_lcount
!= nbytes
);
533 m_error
= (m_lcount
== 0);
535 // Allow write events again
541 wxUint32
wxSocketBase::_Write(const void *buffer
, wxUint32 nbytes
)
545 // If the socket is invalid or parameters are ill, return immediately
546 if (!m_socket
|| !buffer
|| !nbytes
)
549 // Possible combinations (they are checked in this order)
551 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
556 if (m_flags
& wxSOCKET_NOWAIT
)
558 m_socket
->SetNonBlocking(1);
559 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
560 m_socket
->SetNonBlocking(0);
571 if ( !(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite() )
574 ret
= m_socket
->Write((const char *)buffer
, nbytes
);
580 buffer
= (const char *)buffer
+ ret
;
583 // If we got here and wxSOCKET_WAITALL is not set, we can leave
584 // now. Otherwise, wait until we send all the data or until there
587 more
= (ret
> 0 && nbytes
> 0 && (m_flags
& wxSOCKET_WAITALL
));
594 wxSocketBase
& wxSocketBase::WriteMsg(const void *buffer
, wxUint32 nbytes
)
600 unsigned char sig
[4];
601 unsigned char len
[4];
609 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
611 msg
.sig
[0] = (unsigned char) 0xad;
612 msg
.sig
[1] = (unsigned char) 0xde;
613 msg
.sig
[2] = (unsigned char) 0xed;
614 msg
.sig
[3] = (unsigned char) 0xfe;
616 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
617 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
618 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
619 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
621 if (_Write(&msg
, sizeof(msg
)) < sizeof(msg
))
624 total
= _Write(buffer
, nbytes
);
629 msg
.sig
[0] = (unsigned char) 0xed;
630 msg
.sig
[1] = (unsigned char) 0xfe;
631 msg
.sig
[2] = (unsigned char) 0xad;
632 msg
.sig
[3] = (unsigned char) 0xde;
633 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
635 if ((_Write(&msg
, sizeof(msg
))) < sizeof(msg
))
649 wxSocketBase
& wxSocketBase::Unread(const void *buffer
, wxUint32 nbytes
)
652 Pushback(buffer
, nbytes
);
660 wxSocketBase
& wxSocketBase::Discard()
662 char *buffer
= new char[MAX_DISCARD_SIZE
];
669 SetFlags(wxSOCKET_NOWAIT
);
673 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
676 while (ret
== MAX_DISCARD_SIZE
);
682 // Allow read events again
688 // --------------------------------------------------------------------------
690 // --------------------------------------------------------------------------
692 // All Wait functions poll the socket using GSocket_Select() to
693 // check for the specified combination of conditions, until one
694 // of these conditions become true, an error occurs, or the
695 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
696 // this won't block the GUI.
698 bool wxSocketBase::_Wait(long seconds
,
700 wxSocketEventFlags flags
)
702 GSocketEventFlags result
;
703 long timeout
; // in ms
705 // Set this to true to interrupt ongoing waits
708 // Check for valid socket
712 // Check for valid timeout value.
714 timeout
= seconds
* 1000 + milliseconds
;
716 timeout
= m_timeout
* 1000;
718 // check if we are using event loop or not: normally we do in GUI but not in
719 // console applications but this can be overridden
720 const bool has_event_loop
= wxEventLoop::GetActive() != NULL
;
722 // Wait in an active polling loop.
724 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
725 // hurt. It has to be here because the (GSocket) event might arrive
726 // a bit delayed, and it has to be in OnRequest as well because we
727 // don't know whether the Wait functions are being used.
729 // Do this at least once (important if timeout == 0, when
730 // we are just polling). Also, if just polling, do not yield.
732 const wxMilliClock_t time_limit
= wxGetLocalTimeMillis() + timeout
;
734 bool valid_result
= false;
738 // This is used to avoid a busy loop on wxBase - having a select
739 // timeout of 50 ms per iteration should be enough.
741 m_socket
->SetTimeout(50);
743 m_socket
->SetTimeout(timeout
);
748 result
= m_socket
->Select(flags
| GSOCK_LOST_FLAG
);
750 // Incoming connection (server) or connection established (client)
751 if (result
& GSOCK_CONNECTION_FLAG
)
754 m_establishing
= false;
759 // Data available or output buffer ready
760 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
767 if (result
& GSOCK_LOST_FLAG
)
770 m_establishing
= false;
771 valid_result
= ((flags
& GSOCK_LOST_FLAG
) != 0);
776 long time_left
= wxMilliClockToLong(time_limit
- wxGetLocalTimeMillis());
777 if ((!timeout
) || (time_left
<= 0) || (m_interrupt
))
787 // If there's less than 50 ms left, just call select with that timeout.
789 m_socket
->SetTimeout(time_left
);
794 // Set timeout back to original value (we overwrote it for polling)
796 m_socket
->SetTimeout(m_timeout
*1000);
801 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
803 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
805 GSOCK_CONNECTION_FLAG
|
809 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
811 // Check pushback buffer before entering _Wait
815 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
816 // _Wait because of the semantics of WaitForRead: a return
817 // value of true means that a GSocket_Read call will return
818 // immediately, not that there is actually data to read.
820 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
825 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
827 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
830 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
832 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
835 // --------------------------------------------------------------------------
837 // --------------------------------------------------------------------------
840 // Get local or peer address
843 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
850 peer
= m_socket
->GetPeer();
852 // copying a null address would just trigger an assert anyway
857 addr_man
.SetAddress(peer
);
858 GAddress_destroy(peer
);
863 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
870 local
= m_socket
->GetLocal();
871 addr_man
.SetAddress(local
);
872 GAddress_destroy(local
);
878 // Save and restore socket state
881 void wxSocketBase::SaveState()
883 wxSocketState
*state
;
885 state
= new wxSocketState();
887 state
->m_flags
= m_flags
;
888 state
->m_notify
= m_notify
;
889 state
->m_eventmask
= m_eventmask
;
890 state
->m_clientData
= m_clientData
;
892 m_states
.Append(state
);
895 void wxSocketBase::RestoreState()
897 wxList::compatibility_iterator node
;
898 wxSocketState
*state
;
900 node
= m_states
.GetLast();
904 state
= (wxSocketState
*)node
->GetData();
906 m_flags
= state
->m_flags
;
907 m_notify
= state
->m_notify
;
908 m_eventmask
= state
->m_eventmask
;
909 m_clientData
= state
->m_clientData
;
911 m_states
.Erase(node
);
919 void wxSocketBase::SetTimeout(long seconds
)
924 m_socket
->SetTimeout(m_timeout
* 1000);
927 void wxSocketBase::SetFlags(wxSocketFlags flags
)
933 // --------------------------------------------------------------------------
935 // --------------------------------------------------------------------------
937 // A note on how events are processed, which is probably the most
938 // difficult thing to get working right while keeping the same API
939 // and functionality for all platforms.
941 // When GSocket detects an event, it calls wx_socket_callback, which in
942 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
943 // object. OnRequest does some housekeeping, and if the event is to be
944 // propagated to the user, it creates a new wxSocketEvent object and
945 // posts it. The event is not processed immediately, but delayed with
946 // AddPendingEvent instead. This is necessary in order to decouple the
947 // event processing from wx_socket_callback; otherwise, subsequent IO
948 // calls made from the user event handler would fail, as gtk callbacks
949 // are not reentrant.
951 // Note that, unlike events, user callbacks (now deprecated) are _not_
952 // decoupled from wx_socket_callback and thus they suffer from a variety
953 // of problems. Avoid them where possible and use events instead.
956 void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
957 GSocketEvent notification
,
960 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
962 sckobj
->OnRequest((wxSocketNotify
) notification
);
965 void wxSocketBase::OnRequest(wxSocketNotify notification
)
967 // NOTE: We duplicate some of the code in _Wait, but this doesn't
968 // hurt. It has to be here because the (GSocket) event might arrive
969 // a bit delayed, and it has to be in _Wait as well because we don't
970 // know whether the Wait functions are being used.
974 case wxSOCKET_CONNECTION
:
975 m_establishing
= false;
979 // If we are in the middle of a R/W operation, do not
980 // propagate events to users. Also, filter 'late' events
981 // which are no longer valid.
984 if (m_reading
|| !m_socket
->Select(GSOCK_INPUT_FLAG
))
988 case wxSOCKET_OUTPUT
:
989 if (m_writing
|| !m_socket
->Select(GSOCK_OUTPUT_FLAG
))
995 m_establishing
= false;
1002 // Schedule the event
1004 wxSocketEventFlags flag
= 0;
1006 switch (notification
)
1008 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
1009 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
1010 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
1011 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
1013 wxLogWarning(_("wxSocket: unknown event!."));
1017 if (((m_eventmask
& flag
) == flag
) && m_notify
)
1021 wxSocketEvent
event(m_id
);
1022 event
.m_event
= notification
;
1023 event
.m_clientData
= m_clientData
;
1024 event
.SetEventObject(this);
1026 m_handler
->AddPendingEvent(event
);
1031 void wxSocketBase::Notify(bool notify
)
1035 m_socket
->Notify(notify
);
1038 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
1040 m_eventmask
= flags
;
1043 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
1045 m_handler
= &handler
;
1049 // --------------------------------------------------------------------------
1051 // --------------------------------------------------------------------------
1053 void wxSocketBase::Pushback(const void *buffer
, wxUint32 size
)
1057 if (m_unread
== NULL
)
1058 m_unread
= malloc(size
);
1063 tmp
= malloc(m_unrd_size
+ size
);
1064 memcpy((char *)tmp
+ size
, m_unread
, m_unrd_size
);
1070 m_unrd_size
+= size
;
1072 memcpy(m_unread
, buffer
, size
);
1075 wxUint32
wxSocketBase::GetPushback(void *buffer
, wxUint32 size
, bool peek
)
1080 if (size
> (m_unrd_size
-m_unrd_cur
))
1081 size
= m_unrd_size
-m_unrd_cur
;
1083 memcpy(buffer
, (char *)m_unread
+ m_unrd_cur
, size
);
1088 if (m_unrd_size
== m_unrd_cur
)
1101 // ==========================================================================
1103 // ==========================================================================
1105 // --------------------------------------------------------------------------
1107 // --------------------------------------------------------------------------
1109 wxSocketServer::wxSocketServer(const wxSockAddress
& addr_man
,
1110 wxSocketFlags flags
)
1111 : wxSocketBase(flags
, wxSOCKET_SERVER
)
1113 wxLogTrace( wxTRACE_Socket
, _T("Opening wxSocketServer") );
1115 m_socket
= GSocket_new();
1119 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_new failed") );
1123 // Setup the socket as server
1124 m_socket
->Notify(m_notify
);
1125 m_socket
->SetLocal(addr_man
.GetAddress());
1127 if (GetFlags() & wxSOCKET_REUSEADDR
) {
1128 m_socket
->SetReusable();
1130 if (GetFlags() & wxSOCKET_BROADCAST
) {
1131 m_socket
->SetBroadcast();
1133 if (GetFlags() & wxSOCKET_NOBIND
) {
1134 m_socket
->DontDoBind();
1137 if (m_socket
->SetServer() != GSOCK_NOERROR
)
1142 wxLogTrace( wxTRACE_Socket
, _T("*** GSocket_SetServer failed") );
1146 m_socket
->SetTimeout(m_timeout
* 1000);
1147 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1148 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1149 wx_socket_callback
, (char *)this);
1151 wxLogTrace( wxTRACE_Socket
, _T("wxSocketServer on fd %d"), m_socket
->m_fd
);
1154 // --------------------------------------------------------------------------
1156 // --------------------------------------------------------------------------
1158 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1160 GSocket
*child_socket
;
1165 // If wait == false, then the call should be nonblocking.
1166 // When we are finished, we put the socket to blocking mode
1170 m_socket
->SetNonBlocking(1);
1172 child_socket
= m_socket
->WaitConnection();
1175 m_socket
->SetNonBlocking(0);
1180 sock
.m_type
= wxSOCKET_BASE
;
1181 sock
.m_socket
= child_socket
;
1182 sock
.m_connected
= true;
1184 sock
.m_socket
->SetTimeout(sock
.m_timeout
* 1000);
1185 sock
.m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1186 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1187 wx_socket_callback
, (char *)&sock
);
1192 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1194 wxSocketBase
* sock
= new wxSocketBase();
1196 sock
->SetFlags(m_flags
);
1198 if (!AcceptWith(*sock
, wait
))
1207 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1209 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1212 bool wxSocketBase::GetOption(int level
, int optname
, void *optval
, int *optlen
)
1214 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1216 if (m_socket
->GetSockOpt(level
, optname
, optval
, optlen
)
1224 bool wxSocketBase::SetOption(int level
, int optname
, const void *optval
,
1227 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1229 if (m_socket
->SetSockOpt(level
, optname
, optval
, optlen
)
1237 bool wxSocketBase::SetLocal(wxIPV4address
& local
)
1239 GAddress
* la
= local
.GetAddress();
1241 // If the address is valid, save it for use when we call Connect
1242 if (la
&& la
->m_addr
)
1244 m_localAddress
= local
;
1252 // ==========================================================================
1254 // ==========================================================================
1256 // --------------------------------------------------------------------------
1258 // --------------------------------------------------------------------------
1260 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1261 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1263 m_initialRecvBufferSize
=
1264 m_initialSendBufferSize
= -1;
1267 wxSocketClient::~wxSocketClient()
1271 // --------------------------------------------------------------------------
1273 // --------------------------------------------------------------------------
1275 bool wxSocketClient::DoConnect(wxSockAddress
& addr_man
, wxSockAddress
* local
, bool wait
)
1281 // Shutdown and destroy the socket
1286 m_socket
= GSocket_new();
1287 m_connected
= false;
1288 m_establishing
= false;
1293 m_socket
->SetTimeout(m_timeout
* 1000);
1294 m_socket
->SetCallback(GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1295 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1296 wx_socket_callback
, (char *)this);
1298 // If wait == false, then the call should be nonblocking.
1299 // When we are finished, we put the socket to blocking mode
1303 m_socket
->SetNonBlocking(1);
1305 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1306 if (GetFlags() & wxSOCKET_REUSEADDR
)
1308 m_socket
->SetReusable();
1310 if (GetFlags() & wxSOCKET_BROADCAST
)
1312 m_socket
->SetBroadcast();
1314 if (GetFlags() & wxSOCKET_NOBIND
)
1316 m_socket
->DontDoBind();
1319 // If no local address was passed and one has been set, use the one that was Set
1320 if (!local
&& m_localAddress
.GetAddress())
1322 local
= &m_localAddress
;
1325 // Bind to the local IP address and port, when provided
1328 GAddress
* la
= local
->GetAddress();
1330 if (la
&& la
->m_addr
)
1331 m_socket
->SetLocal(la
);
1334 #if defined(__WXMSW__) || defined(__WXGTK__)
1335 m_socket
->SetInitialSocketBuffers(m_initialRecvBufferSize
, m_initialSendBufferSize
);
1338 m_socket
->SetPeer(addr_man
.GetAddress());
1339 err
= m_socket
->Connect(GSOCK_STREAMED
);
1341 //this will register for callbacks - must be called after m_socket->m_fd was initialized
1342 m_socket
->Notify(m_notify
);
1345 m_socket
->SetNonBlocking(0);
1347 if (err
!= GSOCK_NOERROR
)
1349 if (err
== GSOCK_WOULDBLOCK
)
1350 m_establishing
= true;
1359 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1361 return (DoConnect(addr_man
, NULL
, wait
));
1364 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, wxSockAddress
& local
, bool wait
)
1366 return (DoConnect(addr_man
, &local
, wait
));
1369 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1371 if (m_connected
) // Already connected
1374 if (!m_establishing
|| !m_socket
) // No connection in progress
1377 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1381 // ==========================================================================
1383 // ==========================================================================
1385 /* NOTE: experimental stuff - might change */
1387 wxDatagramSocket::wxDatagramSocket( const wxSockAddress
& addr
,
1388 wxSocketFlags flags
)
1389 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1391 // Create the socket
1392 m_socket
= GSocket_new();
1396 wxFAIL_MSG( _T("datagram socket not new'd") );
1399 m_socket
->Notify(m_notify
);
1400 // Setup the socket as non connection oriented
1401 m_socket
->SetLocal(addr
.GetAddress());
1402 if (flags
& wxSOCKET_REUSEADDR
)
1404 m_socket
->SetReusable();
1406 if (GetFlags() & wxSOCKET_BROADCAST
)
1408 m_socket
->SetBroadcast();
1410 if (GetFlags() & wxSOCKET_NOBIND
)
1412 m_socket
->DontDoBind();
1414 if ( m_socket
->SetNonOriented() != GSOCK_NOERROR
)
1421 // Initialize all stuff
1422 m_connected
= false;
1423 m_establishing
= false;
1424 m_socket
->SetTimeout( m_timeout
);
1425 m_socket
->SetCallback( GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1426 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1427 wx_socket_callback
, (char*)this );
1430 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1439 wxDatagramSocket
& wxDatagramSocket::SendTo( const wxSockAddress
& addr
,
1443 wxASSERT_MSG( m_socket
, _T("Socket not initialised") );
1445 m_socket
->SetPeer(addr
.GetAddress());
1450 // ==========================================================================
1452 // ==========================================================================
1454 class wxSocketModule
: public wxModule
1457 virtual bool OnInit()
1459 // wxSocketBase will call GSocket_Init() itself when/if needed
1463 virtual void OnExit()
1465 if ( wxSocketBase::IsInitialized() )
1466 wxSocketBase::Shutdown();
1470 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1473 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)