]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/socket.cpp
Add missing WXK constants for the control keys
[wxWidgets.git] / src / common / socket.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/common/socket.cpp
3// Purpose: Socket handler classes
4// Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
5// Created: April 1997
6// Copyright: (C) 1999-1997, Guilhem Lavaux
7// (C) 1999-2000, Guillermo Rodriguez Garcia
8// (C) 2008 Vadim Zeitlin
9// RCS_ID: $Id$
10// Licence: wxWindows licence
11/////////////////////////////////////////////////////////////////////////////
12
13// ==========================================================================
14// Declarations
15// ==========================================================================
16
17// For compilers that support precompilation, includes "wx.h".
18#include "wx/wxprec.h"
19
20#ifdef __BORLANDC__
21 #pragma hdrstop
22#endif
23
24#if wxUSE_SOCKETS
25
26#include "wx/socket.h"
27
28#ifndef WX_PRECOMP
29 #include "wx/object.h"
30 #include "wx/string.h"
31 #include "wx/intl.h"
32 #include "wx/log.h"
33 #include "wx/event.h"
34 #include "wx/app.h"
35 #include "wx/utils.h"
36 #include "wx/timer.h"
37 #include "wx/module.h"
38#endif
39
40#include "wx/apptrait.h"
41#include "wx/sckaddr.h"
42#include "wx/stopwatch.h"
43#include "wx/thread.h"
44#include "wx/evtloop.h"
45#include "wx/link.h"
46
47#include "wx/private/fd.h"
48#include "wx/private/socket.h"
49
50#ifdef __UNIX__
51 #include <errno.h>
52#endif
53
54// we use MSG_NOSIGNAL to avoid getting SIGPIPE when sending data to a remote
55// host which closed the connection if it is available, otherwise we rely on
56// SO_NOSIGPIPE existency
57//
58// this should cover all the current Unix systems (Windows never sends any
59// signals anyhow) but if we find one that has neither we should explicitly
60// ignore SIGPIPE for it
61// OpenVMS has neither MSG_NOSIGNAL nor SO_NOSIGPIPE. However the socket sample
62// seems to work. Not sure if problems will show up on OpenVMS using sockets.
63#ifdef MSG_NOSIGNAL
64 #define wxSOCKET_MSG_NOSIGNAL MSG_NOSIGNAL
65#else // MSG_NOSIGNAL not available (BSD including OS X)
66 // next best possibility is to use SO_NOSIGPIPE socket option, this covers
67 // BSD systems (including OS X) -- but if we don't have it neither (AIX and
68 // old HP-UX do not), we have to fall back to the old way of simply
69 // disabling SIGPIPE temporarily, so define a class to do it in a safe way
70 #if defined(__UNIX__) && !defined(SO_NOSIGPIPE)
71 extern "C" { typedef void (*wxSigHandler_t)(int); }
72 namespace
73 {
74 class IgnoreSignal
75 {
76 public:
77 // ctor disables the given signal
78 IgnoreSignal(int sig)
79 : m_handler(signal(sig, SIG_IGN)),
80 m_sig(sig)
81 {
82 }
83
84 // dtor restores the old handler
85 ~IgnoreSignal()
86 {
87 signal(m_sig, m_handler);
88 }
89
90 private:
91 const wxSigHandler_t m_handler;
92 const int m_sig;
93
94 wxDECLARE_NO_COPY_CLASS(IgnoreSignal);
95 };
96 } // anonymous namespace
97
98 #define wxNEEDS_IGNORE_SIGPIPE
99 #endif // Unix without SO_NOSIGPIPE
100
101 #define wxSOCKET_MSG_NOSIGNAL 0
102#endif
103
104// DLL options compatibility check:
105#include "wx/build.h"
106WX_CHECK_BUILD_OPTIONS("wxNet")
107
108// --------------------------------------------------------------------------
109// macros and constants
110// --------------------------------------------------------------------------
111
112// event
113wxDEFINE_EVENT(wxEVT_SOCKET, wxSocketEvent);
114
115// discard buffer
116#define MAX_DISCARD_SIZE (10 * 1024)
117
118#define wxTRACE_Socket wxT("wxSocket")
119
120// --------------------------------------------------------------------------
121// wxWin macros
122// --------------------------------------------------------------------------
123
124IMPLEMENT_CLASS(wxSocketBase, wxObject)
125IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
126IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
127IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
128IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
129
130// ----------------------------------------------------------------------------
131// private functions
132// ----------------------------------------------------------------------------
133
134namespace
135{
136
137void SetTimeValFromMS(timeval& tv, unsigned long ms)
138{
139 tv.tv_sec = (ms / 1000);
140 tv.tv_usec = (ms % 1000) * 1000;
141}
142
143} // anonymous namespace
144
145// --------------------------------------------------------------------------
146// private classes
147// --------------------------------------------------------------------------
148
149class wxSocketState : public wxObject
150{
151public:
152 wxSocketFlags m_flags;
153 wxSocketEventFlags m_eventmask;
154 bool m_notify;
155 void *m_clientData;
156
157public:
158 wxSocketState() : wxObject() {}
159
160 wxDECLARE_NO_COPY_CLASS(wxSocketState);
161};
162
163// wxSocketWaitModeChanger: temporarily change the socket flags affecting its
164// wait mode
165class wxSocketWaitModeChanger
166{
167public:
168 // temporarily set the flags to include the flag value which may be either
169 // wxSOCKET_NOWAIT or wxSOCKET_WAITALL
170 wxSocketWaitModeChanger(wxSocketBase *socket, int flag)
171 : m_socket(socket),
172 m_oldflags(socket->GetFlags())
173
174 {
175 wxASSERT_MSG( flag == wxSOCKET_WAITALL || flag == wxSOCKET_NOWAIT,
176 "not a wait flag" );
177
178 // preserve wxSOCKET_BLOCK value when switching to wxSOCKET_WAITALL
179 // mode but not when switching to wxSOCKET_NOWAIT as the latter is
180 // incompatible with wxSOCKET_BLOCK
181 if ( flag != wxSOCKET_NOWAIT )
182 flag |= m_oldflags & wxSOCKET_BLOCK;
183
184 socket->SetFlags(flag);
185 }
186
187 ~wxSocketWaitModeChanger()
188 {
189 m_socket->SetFlags(m_oldflags);
190 }
191
192private:
193 wxSocketBase * const m_socket;
194 const int m_oldflags;
195
196 wxDECLARE_NO_COPY_CLASS(wxSocketWaitModeChanger);
197};
198
199// wxSocketRead/WriteGuard are instantiated before starting reading
200// from/writing to the socket
201class wxSocketReadGuard
202{
203public:
204 wxSocketReadGuard(wxSocketBase *socket)
205 : m_socket(socket)
206 {
207 wxASSERT_MSG( !m_socket->m_reading, "read reentrancy?" );
208
209 m_socket->m_reading = true;
210 }
211
212 ~wxSocketReadGuard()
213 {
214 m_socket->m_reading = false;
215
216 // connection could have been lost while reading, in this case calling
217 // ReenableEvents() would assert and is not necessary anyhow
218 wxSocketImpl * const impl = m_socket->m_impl;
219 if ( impl && impl->m_fd != INVALID_SOCKET )
220 impl->ReenableEvents(wxSOCKET_INPUT_FLAG);
221 }
222
223private:
224 wxSocketBase * const m_socket;
225
226 wxDECLARE_NO_COPY_CLASS(wxSocketReadGuard);
227};
228
229class wxSocketWriteGuard
230{
231public:
232 wxSocketWriteGuard(wxSocketBase *socket)
233 : m_socket(socket)
234 {
235 wxASSERT_MSG( !m_socket->m_writing, "write reentrancy?" );
236
237 m_socket->m_writing = true;
238 }
239
240 ~wxSocketWriteGuard()
241 {
242 m_socket->m_writing = false;
243
244 wxSocketImpl * const impl = m_socket->m_impl;
245 if ( impl && impl->m_fd != INVALID_SOCKET )
246 impl->ReenableEvents(wxSOCKET_OUTPUT_FLAG);
247 }
248
249private:
250 wxSocketBase * const m_socket;
251
252 wxDECLARE_NO_COPY_CLASS(wxSocketWriteGuard);
253};
254
255// ============================================================================
256// wxSocketManager
257// ============================================================================
258
259wxSocketManager *wxSocketManager::ms_manager = NULL;
260
261/* static */
262void wxSocketManager::Set(wxSocketManager *manager)
263{
264 wxASSERT_MSG( !ms_manager, "too late to set manager now" );
265
266 ms_manager = manager;
267}
268
269/* static */
270void wxSocketManager::Init()
271{
272 wxASSERT_MSG( !ms_manager, "shouldn't be initialized twice" );
273
274 /*
275 Details: Initialize() creates a hidden window as a sink for socket
276 events, such as 'read completed'. wxMSW has only one message loop
277 for the main thread. If Initialize is called in a secondary thread,
278 the socket window will be created for the secondary thread, but
279 since there is no message loop on this thread, it will never
280 receive events and all socket operations will time out.
281 BTW, the main thread must not be stopped using sleep or block
282 on a semaphore (a bad idea in any case) or socket operations
283 will time out.
284
285 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
286 the main thread. Because secondary threads do not have run loops,
287 adding event notifications to the "Current" loop would have no
288 effect at all, events would never fire.
289 */
290 wxASSERT_MSG( wxIsMainThread(),
291 "sockets must be initialized from the main thread" );
292
293 wxAppConsole * const app = wxAppConsole::GetInstance();
294 wxCHECK_RET( app, "sockets can't be initialized without wxApp" );
295
296 ms_manager = app->GetTraits()->GetSocketManager();
297}
298
299// ==========================================================================
300// wxSocketImpl
301// ==========================================================================
302
303wxSocketImpl::wxSocketImpl(wxSocketBase& wxsocket)
304 : m_wxsocket(&wxsocket)
305{
306 m_fd = INVALID_SOCKET;
307 m_error = wxSOCKET_NOERROR;
308 m_server = false;
309 m_stream = true;
310
311 SetTimeout(wxsocket.GetTimeout() * 1000);
312
313 m_establishing = false;
314 m_reusable = false;
315 m_broadcast = false;
316 m_dobind = true;
317 m_initialRecvBufferSize = -1;
318 m_initialSendBufferSize = -1;
319}
320
321wxSocketImpl::~wxSocketImpl()
322{
323 if ( m_fd != INVALID_SOCKET )
324 Shutdown();
325}
326
327bool wxSocketImpl::PreCreateCheck(const wxSockAddressImpl& addr)
328{
329 if ( m_fd != INVALID_SOCKET )
330 {
331 m_error = wxSOCKET_INVSOCK;
332 return false;
333 }
334
335 if ( !addr.IsOk() )
336 {
337 m_error = wxSOCKET_INVADDR;
338 return false;
339 }
340
341 return true;
342}
343
344void wxSocketImpl::PostCreation()
345{
346 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
347#ifdef SO_NOSIGPIPE
348 EnableSocketOption(SO_NOSIGPIPE);
349#endif
350
351 if ( m_reusable )
352 EnableSocketOption(SO_REUSEADDR);
353
354 if ( m_broadcast )
355 {
356 wxASSERT_MSG( !m_stream, "broadcasting is for datagram sockets only" );
357
358 EnableSocketOption(SO_BROADCAST);
359 }
360
361 if ( m_initialRecvBufferSize >= 0 )
362 SetSocketOption(SO_RCVBUF, m_initialRecvBufferSize);
363 if ( m_initialSendBufferSize >= 0 )
364 SetSocketOption(SO_SNDBUF, m_initialSendBufferSize);
365
366 // we always put our sockets in unblocked mode and handle blocking
367 // ourselves in DoRead/Write() if wxSOCKET_WAITALL is specified
368 UnblockAndRegisterWithEventLoop();
369}
370
371wxSocketError wxSocketImpl::UpdateLocalAddress()
372{
373 if ( !m_local.IsOk() )
374 {
375 // ensure that we have a valid object using the correct family: correct
376 // being the same one as our peer uses as we have no other way to
377 // determine it
378 m_local.Create(m_peer.GetFamily());
379 }
380
381 WX_SOCKLEN_T lenAddr = m_local.GetLen();
382 if ( getsockname(m_fd, m_local.GetWritableAddr(), &lenAddr) != 0 )
383 {
384 Close();
385 m_error = wxSOCKET_IOERR;
386 return m_error;
387 }
388
389 return wxSOCKET_NOERROR;
390}
391
392wxSocketError wxSocketImpl::CreateServer()
393{
394 if ( !PreCreateCheck(m_local) )
395 return m_error;
396
397 m_server = true;
398 m_stream = true;
399
400 // do create the socket
401 m_fd = socket(m_local.GetFamily(), SOCK_STREAM, 0);
402
403 if ( m_fd == INVALID_SOCKET )
404 {
405 m_error = wxSOCKET_IOERR;
406 return wxSOCKET_IOERR;
407 }
408
409 PostCreation();
410
411 // and then bind to and listen on it
412 //
413 // FIXME: should we test for m_dobind here?
414 if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
415 m_error = wxSOCKET_IOERR;
416
417 if ( IsOk() )
418 {
419 if ( listen(m_fd, 5) != 0 )
420 m_error = wxSOCKET_IOERR;
421 }
422
423 if ( !IsOk() )
424 {
425 Close();
426 return m_error;
427 }
428
429 // finally retrieve the address we effectively bound to
430 return UpdateLocalAddress();
431}
432
433wxSocketError wxSocketImpl::CreateClient(bool wait)
434{
435 if ( !PreCreateCheck(m_peer) )
436 return m_error;
437
438 m_fd = socket(m_peer.GetFamily(), SOCK_STREAM, 0);
439
440 if ( m_fd == INVALID_SOCKET )
441 {
442 m_error = wxSOCKET_IOERR;
443 return wxSOCKET_IOERR;
444 }
445
446 PostCreation();
447
448 // If a local address has been set, then bind to it before calling connect
449 if ( m_local.IsOk() )
450 {
451 if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
452 {
453 Close();
454 m_error = wxSOCKET_IOERR;
455 return m_error;
456 }
457 }
458
459 // Do connect now
460 int rc = connect(m_fd, m_peer.GetAddr(), m_peer.GetLen());
461 if ( rc == SOCKET_ERROR )
462 {
463 wxSocketError err = GetLastError();
464 if ( err == wxSOCKET_WOULDBLOCK )
465 {
466 m_establishing = true;
467
468 // block waiting for connection if we should (otherwise just return
469 // wxSOCKET_WOULDBLOCK to the caller)
470 if ( wait )
471 {
472 err = SelectWithTimeout(wxSOCKET_CONNECTION_FLAG)
473 ? wxSOCKET_NOERROR
474 : wxSOCKET_TIMEDOUT;
475 m_establishing = false;
476 }
477 }
478
479 m_error = err;
480 }
481 else // connected
482 {
483 m_error = wxSOCKET_NOERROR;
484 }
485
486 return m_error;
487}
488
489
490wxSocketError wxSocketImpl::CreateUDP()
491{
492 if ( !PreCreateCheck(m_local) )
493 return m_error;
494
495 m_stream = false;
496 m_server = false;
497
498 m_fd = socket(m_local.GetFamily(), SOCK_DGRAM, 0);
499
500 if ( m_fd == INVALID_SOCKET )
501 {
502 m_error = wxSOCKET_IOERR;
503 return wxSOCKET_IOERR;
504 }
505
506 PostCreation();
507
508 if ( m_dobind )
509 {
510 if ( bind(m_fd, m_local.GetAddr(), m_local.GetLen()) != 0 )
511 {
512 Close();
513 m_error = wxSOCKET_IOERR;
514 return m_error;
515 }
516
517 return UpdateLocalAddress();
518 }
519
520 return wxSOCKET_NOERROR;
521}
522
523wxSocketImpl *wxSocketImpl::Accept(wxSocketBase& wxsocket)
524{
525 wxSockAddressStorage from;
526 WX_SOCKLEN_T fromlen = sizeof(from);
527 const SOCKET fd = accept(m_fd, &from.addr, &fromlen);
528
529 // accepting is similar to reading in the sense that it resets "ready for
530 // read" flag on the socket
531 ReenableEvents(wxSOCKET_INPUT_FLAG);
532
533 if ( fd == INVALID_SOCKET )
534 return NULL;
535
536 wxSocketManager * const manager = wxSocketManager::Get();
537 if ( !manager )
538 return NULL;
539
540 wxSocketImpl * const sock = manager->CreateSocket(wxsocket);
541 if ( !sock )
542 return NULL;
543
544 sock->m_fd = fd;
545 sock->m_peer = wxSockAddressImpl(from.addr, fromlen);
546
547 sock->UnblockAndRegisterWithEventLoop();
548
549 return sock;
550}
551
552
553void wxSocketImpl::Close()
554{
555 if ( m_fd != INVALID_SOCKET )
556 {
557 DoClose();
558 m_fd = INVALID_SOCKET;
559 }
560}
561
562void wxSocketImpl::Shutdown()
563{
564 if ( m_fd != INVALID_SOCKET )
565 {
566 shutdown(m_fd, 1 /* SD_SEND */);
567 Close();
568 }
569}
570
571/*
572 * Sets the timeout for blocking calls. Time is expressed in
573 * milliseconds.
574 */
575void wxSocketImpl::SetTimeout(unsigned long millis)
576{
577 SetTimeValFromMS(m_timeout, millis);
578}
579
580void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event)
581{
582 m_wxsocket->OnRequest(event);
583}
584
585/* Address handling */
586wxSocketError wxSocketImpl::SetLocal(const wxSockAddressImpl& local)
587{
588 /* the socket must be initialized, or it must be a server */
589 if (m_fd != INVALID_SOCKET && !m_server)
590 {
591 m_error = wxSOCKET_INVSOCK;
592 return wxSOCKET_INVSOCK;
593 }
594
595 if ( !local.IsOk() )
596 {
597 m_error = wxSOCKET_INVADDR;
598 return wxSOCKET_INVADDR;
599 }
600
601 m_local = local;
602
603 return wxSOCKET_NOERROR;
604}
605
606wxSocketError wxSocketImpl::SetPeer(const wxSockAddressImpl& peer)
607{
608 if ( !peer.IsOk() )
609 {
610 m_error = wxSOCKET_INVADDR;
611 return wxSOCKET_INVADDR;
612 }
613
614 m_peer = peer;
615
616 return wxSOCKET_NOERROR;
617}
618
619const wxSockAddressImpl& wxSocketImpl::GetLocal()
620{
621 if ( !m_local.IsOk() )
622 UpdateLocalAddress();
623
624 return m_local;
625}
626
627// ----------------------------------------------------------------------------
628// wxSocketImpl IO
629// ----------------------------------------------------------------------------
630
631// this macro wraps the given expression (normally a syscall) in a loop which
632// ignores any interruptions, i.e. reevaluates it again if it failed and errno
633// is EINTR
634#ifdef __UNIX__
635 #define DO_WHILE_EINTR( rc, syscall ) \
636 do { \
637 rc = (syscall); \
638 } \
639 while ( rc == -1 && errno == EINTR )
640#else
641 #define DO_WHILE_EINTR( rc, syscall ) rc = (syscall)
642#endif
643
644int wxSocketImpl::RecvStream(void *buffer, int size)
645{
646 int ret;
647 DO_WHILE_EINTR( ret, recv(m_fd, static_cast<char *>(buffer), size, 0) );
648
649 if ( !ret )
650 {
651 // receiving 0 bytes for a TCP socket indicates that the connection was
652 // closed by peer so shut down our end as well (for UDP sockets empty
653 // datagrams are also possible)
654 m_establishing = false;
655 NotifyOnStateChange(wxSOCKET_LOST);
656
657 Shutdown();
658
659 // do not return an error in this case however
660 }
661
662 return ret;
663}
664
665int wxSocketImpl::SendStream(const void *buffer, int size)
666{
667#ifdef wxNEEDS_IGNORE_SIGPIPE
668 IgnoreSignal ignore(SIGPIPE);
669#endif
670
671 int ret;
672 DO_WHILE_EINTR( ret, send(m_fd, static_cast<const char *>(buffer), size,
673 wxSOCKET_MSG_NOSIGNAL) );
674
675 return ret;
676}
677
678int wxSocketImpl::RecvDgram(void *buffer, int size)
679{
680 wxSockAddressStorage from;
681 WX_SOCKLEN_T fromlen = sizeof(from);
682
683 int ret;
684 DO_WHILE_EINTR( ret, recvfrom(m_fd, static_cast<char *>(buffer), size,
685 0, &from.addr, &fromlen) );
686
687 if ( ret == SOCKET_ERROR )
688 return SOCKET_ERROR;
689
690 m_peer = wxSockAddressImpl(from.addr, fromlen);
691 if ( !m_peer.IsOk() )
692 return -1;
693
694 return ret;
695}
696
697int wxSocketImpl::SendDgram(const void *buffer, int size)
698{
699 if ( !m_peer.IsOk() )
700 {
701 m_error = wxSOCKET_INVADDR;
702 return -1;
703 }
704
705 int ret;
706 DO_WHILE_EINTR( ret, sendto(m_fd, static_cast<const char *>(buffer), size,
707 0, m_peer.GetAddr(), m_peer.GetLen()) );
708
709 return ret;
710}
711
712int wxSocketImpl::Read(void *buffer, int size)
713{
714 // server sockets can't be used for IO, only to accept new connections
715 if ( m_fd == INVALID_SOCKET || m_server )
716 {
717 m_error = wxSOCKET_INVSOCK;
718 return -1;
719 }
720
721 int ret = m_stream ? RecvStream(buffer, size)
722 : RecvDgram(buffer, size);
723
724 m_error = ret == SOCKET_ERROR ? GetLastError() : wxSOCKET_NOERROR;
725
726 return ret;
727}
728
729int wxSocketImpl::Write(const void *buffer, int size)
730{
731 if ( m_fd == INVALID_SOCKET || m_server )
732 {
733 m_error = wxSOCKET_INVSOCK;
734 return -1;
735 }
736
737 int ret = m_stream ? SendStream(buffer, size)
738 : SendDgram(buffer, size);
739
740 m_error = ret == SOCKET_ERROR ? GetLastError() : wxSOCKET_NOERROR;
741
742 return ret;
743}
744
745// ==========================================================================
746// wxSocketBase
747// ==========================================================================
748
749// --------------------------------------------------------------------------
750// Initialization and shutdown
751// --------------------------------------------------------------------------
752
753namespace
754{
755
756// counts the number of calls to Initialize() minus the number of calls to
757// Shutdown(): we don't really need it any more but it was documented that
758// Shutdown() must be called the same number of times as Initialize() and using
759// a counter helps us to check it
760int gs_socketInitCount = 0;
761
762} // anonymous namespace
763
764bool wxSocketBase::IsInitialized()
765{
766 wxASSERT_MSG( wxIsMainThread(), "unsafe to call from other threads" );
767
768 return gs_socketInitCount != 0;
769}
770
771bool wxSocketBase::Initialize()
772{
773 wxCHECK_MSG( wxIsMainThread(), false,
774 "must be called from the main thread" );
775
776 if ( !gs_socketInitCount )
777 {
778 wxSocketManager * const manager = wxSocketManager::Get();
779 if ( !manager || !manager->OnInit() )
780 return false;
781 }
782
783 gs_socketInitCount++;
784
785 return true;
786}
787
788void wxSocketBase::Shutdown()
789{
790 wxCHECK_RET( wxIsMainThread(), "must be called from the main thread" );
791
792 wxCHECK_RET( gs_socketInitCount > 0, "too many calls to Shutdown()" );
793
794 if ( !--gs_socketInitCount )
795 {
796 wxSocketManager * const manager = wxSocketManager::Get();
797 wxCHECK_RET( manager, "should have a socket manager" );
798
799 manager->OnExit();
800 }
801}
802
803// --------------------------------------------------------------------------
804// Ctor and dtor
805// --------------------------------------------------------------------------
806
807void wxSocketBase::Init()
808{
809 m_impl = NULL;
810 m_type = wxSOCKET_UNINIT;
811
812 // state
813 m_flags = 0;
814 m_connected =
815 m_establishing =
816 m_reading =
817 m_writing =
818 m_closed = false;
819 m_lcount = 0;
820 m_lcount_read = 0;
821 m_lcount_write = 0;
822 m_timeout = 600;
823 m_beingDeleted = false;
824
825 // pushback buffer
826 m_unread = NULL;
827 m_unrd_size = 0;
828 m_unrd_cur = 0;
829
830 // events
831 m_id = wxID_ANY;
832 m_handler = NULL;
833 m_clientData = NULL;
834 m_notify = false;
835 m_eventmask =
836 m_eventsgot = 0;
837
838 // when we create the first socket in the main thread we initialize the
839 // OS-dependent socket stuff: notice that this means that the user code
840 // needs to call wxSocket::Initialize() itself if the first socket it
841 // creates is not created in the main thread
842 if ( wxIsMainThread() )
843 {
844 if ( !Initialize() )
845 {
846 wxLogError(_("Cannot initialize sockets"));
847 }
848 }
849}
850
851wxSocketBase::wxSocketBase()
852{
853 Init();
854}
855
856wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
857{
858 Init();
859
860 SetFlags(flags);
861
862 m_type = type;
863}
864
865wxSocketBase::~wxSocketBase()
866{
867 // Shutdown and close the socket
868 if (!m_beingDeleted)
869 Close();
870
871 // Destroy the implementation object
872 delete m_impl;
873
874 // Free the pushback buffer
875 free(m_unread);
876}
877
878bool wxSocketBase::Destroy()
879{
880 // Delayed destruction: the socket will be deleted during the next idle
881 // loop iteration. This ensures that all pending events have been
882 // processed.
883 m_beingDeleted = true;
884
885 // Shutdown and close the socket
886 Close();
887
888 // Suppress events from now on
889 Notify(false);
890
891 // Schedule this object for deletion instead of destroying it right now if
892 // it can have other events pending for it and we have a way to do it.
893 //
894 // Notice that sockets used in other threads won't have any events for them
895 // and we shouldn't use delayed destruction mechanism for them as it's not
896 // MT-safe.
897 if ( wxIsMainThread() && wxTheApp )
898 {
899 wxTheApp->ScheduleForDestruction(this);
900 }
901 else // no app
902 {
903 // in wxBase we might have no app object at all, don't leak memory
904 delete this;
905 }
906
907 return true;
908}
909
910// ----------------------------------------------------------------------------
911// simple accessors
912// ----------------------------------------------------------------------------
913
914void wxSocketBase::SetError(wxSocketError error)
915{
916 m_impl->m_error = error;
917}
918
919wxSocketError wxSocketBase::LastError() const
920{
921 return m_impl->GetError();
922}
923
924// --------------------------------------------------------------------------
925// Basic IO calls
926// --------------------------------------------------------------------------
927
928// The following IO operations update m_lcount:
929// {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
930bool wxSocketBase::Close()
931{
932 // Interrupt pending waits
933 InterruptWait();
934
935 ShutdownOutput();
936
937 m_connected = false;
938 m_establishing = false;
939 return true;
940}
941
942void wxSocketBase::ShutdownOutput()
943{
944 if ( m_impl )
945 m_impl->Shutdown();
946}
947
948wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
949{
950 wxSocketReadGuard read(this);
951
952 m_lcount_read = DoRead(buffer, nbytes);
953 m_lcount = m_lcount_read;
954
955 return *this;
956}
957
958wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
959{
960 wxCHECK_MSG( m_impl, 0, "socket must be valid" );
961
962 // We use pointer arithmetic here which doesn't work with void pointers.
963 char *buffer = static_cast<char *>(buffer_);
964 wxCHECK_MSG( buffer, 0, "NULL buffer" );
965
966 // Try the push back buffer first, even before checking whether the socket
967 // is valid to allow reading previously pushed back data from an already
968 // closed socket.
969 wxUint32 total = GetPushback(buffer, nbytes, false);
970 nbytes -= total;
971 buffer += total;
972
973 while ( nbytes )
974 {
975 // our socket is non-blocking so Read() will return immediately if
976 // there is nothing to read yet and it's more efficient to try it first
977 // before entering DoWait() which is going to start dispatching GUI
978 // events and, even more importantly, we must do this under Windows
979 // where we're not going to get notifications about socket being ready
980 // for reading before we read all the existing data from it
981 const int ret = !m_impl->m_stream || m_connected
982 ? m_impl->Read(buffer, nbytes)
983 : 0;
984 if ( ret == -1 )
985 {
986 if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
987 {
988 // if we don't want to wait, just return immediately
989 if ( m_flags & (wxSOCKET_NOWAIT|wxSOCKET_NOWAIT_READ ))
990 {
991 // this shouldn't be counted as an error in this case
992 SetError(wxSOCKET_NOERROR);
993 break;
994 }
995
996 // otherwise wait until the socket becomes ready for reading or
997 // an error occurs on it
998 if ( !DoWaitWithTimeout(wxSOCKET_INPUT_FLAG) )
999 {
1000 // and exit if the timeout elapsed before it did
1001 SetError(wxSOCKET_TIMEDOUT);
1002 break;
1003 }
1004
1005 // retry reading
1006 continue;
1007 }
1008 else // "real" error
1009 {
1010 SetError(wxSOCKET_IOERR);
1011 break;
1012 }
1013 }
1014 else if ( ret == 0 )
1015 {
1016 // for connection-oriented (e.g. TCP) sockets we can only read
1017 // 0 bytes if the other end has been closed, and for connectionless
1018 // ones (UDP) this flag doesn't make sense anyhow so we can set it
1019 // to true too without doing any harm
1020 m_closed = true;
1021
1022 // we're not going to read anything else and so if we haven't read
1023 // anything (or not everything in wxSOCKET_WAITALL case) already,
1024 // signal an error
1025 if ( (m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_READ)) || !total )
1026 SetError(wxSOCKET_IOERR);
1027 break;
1028 }
1029
1030 total += ret;
1031
1032 // if we are happy to read something and not the entire nbytes bytes,
1033 // then we're done
1034 if ( !(m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_READ)) )
1035 break;
1036
1037 nbytes -= ret;
1038 buffer += ret;
1039 }
1040
1041 return total;
1042}
1043
1044wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
1045{
1046 struct
1047 {
1048 unsigned char sig[4];
1049 unsigned char len[4];
1050 } msg;
1051
1052 wxSocketReadGuard read(this);
1053
1054 wxSocketWaitModeChanger changeFlags(this, (wxSOCKET_WAITALL|wxSOCKET_WAITALL_READ));
1055
1056 bool ok = false;
1057 if ( DoRead(&msg, sizeof(msg)) == sizeof(msg) )
1058 {
1059 wxUint32 sig = (wxUint32)msg.sig[0];
1060 sig |= (wxUint32)(msg.sig[1] << 8);
1061 sig |= (wxUint32)(msg.sig[2] << 16);
1062 sig |= (wxUint32)(msg.sig[3] << 24);
1063
1064 if ( sig == 0xfeeddead )
1065 {
1066 wxUint32 len = (wxUint32)msg.len[0];
1067 len |= (wxUint32)(msg.len[1] << 8);
1068 len |= (wxUint32)(msg.len[2] << 16);
1069 len |= (wxUint32)(msg.len[3] << 24);
1070
1071 wxUint32 len2;
1072 if (len > nbytes)
1073 {
1074 len2 = len - nbytes;
1075 len = nbytes;
1076 }
1077 else
1078 len2 = 0;
1079
1080 // Don't attempt to read if the msg was zero bytes long.
1081 m_lcount_read = len ? DoRead(buffer, len) : 0;
1082 m_lcount = m_lcount_read;
1083
1084 if ( len2 )
1085 {
1086 char discard_buffer[MAX_DISCARD_SIZE];
1087 long discard_len;
1088
1089 // NOTE: discarded bytes don't add to m_lcount.
1090 do
1091 {
1092 discard_len = len2 > MAX_DISCARD_SIZE
1093 ? MAX_DISCARD_SIZE
1094 : len2;
1095 discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
1096 len2 -= (wxUint32)discard_len;
1097 }
1098 while ((discard_len > 0) && len2);
1099 }
1100
1101 if ( !len2 && DoRead(&msg, sizeof(msg)) == sizeof(msg) )
1102 {
1103 sig = (wxUint32)msg.sig[0];
1104 sig |= (wxUint32)(msg.sig[1] << 8);
1105 sig |= (wxUint32)(msg.sig[2] << 16);
1106 sig |= (wxUint32)(msg.sig[3] << 24);
1107
1108 if ( sig == 0xdeadfeed )
1109 ok = true;
1110 }
1111 }
1112 }
1113
1114 if ( !ok )
1115 SetError(wxSOCKET_IOERR);
1116
1117 return *this;
1118}
1119
1120wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
1121{
1122 wxSocketReadGuard read(this);
1123
1124 // Peek() should never block
1125 wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT);
1126
1127 m_lcount = DoRead(buffer, nbytes);
1128
1129 Pushback(buffer, m_lcount);
1130
1131 return *this;
1132}
1133
1134wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
1135{
1136 wxSocketWriteGuard write(this);
1137
1138 m_lcount_write = DoWrite(buffer, nbytes);
1139 m_lcount = m_lcount_write;
1140
1141 return *this;
1142}
1143
1144// This function is a mirror image of DoRead() except that it doesn't use the
1145// push back buffer and doesn't treat 0 return value specially (normally this
1146// shouldn't happen at all here), so please see comments there for explanations
1147wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
1148{
1149 wxCHECK_MSG( m_impl, 0, "socket must be valid" );
1150
1151 const char *buffer = static_cast<const char *>(buffer_);
1152 wxCHECK_MSG( buffer, 0, "NULL buffer" );
1153
1154 wxUint32 total = 0;
1155 while ( nbytes )
1156 {
1157 if ( m_impl->m_stream && !m_connected )
1158 {
1159 if ( (m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_WRITE)) || !total )
1160 SetError(wxSOCKET_IOERR);
1161 break;
1162 }
1163
1164 const int ret = m_impl->Write(buffer, nbytes);
1165 if ( ret == -1 )
1166 {
1167 if ( m_impl->GetLastError() == wxSOCKET_WOULDBLOCK )
1168 {
1169 if ( m_flags & (wxSOCKET_NOWAIT|wxSOCKET_NOWAIT_WRITE) )
1170 break;
1171
1172 if ( !DoWaitWithTimeout(wxSOCKET_OUTPUT_FLAG) )
1173 {
1174 SetError(wxSOCKET_TIMEDOUT);
1175 break;
1176 }
1177
1178 continue;
1179 }
1180 else // "real" error
1181 {
1182 SetError(wxSOCKET_IOERR);
1183 break;
1184 }
1185 }
1186
1187 total += ret;
1188
1189 if ( !(m_flags & (wxSOCKET_WAITALL|wxSOCKET_WAITALL_WRITE)) )
1190 break;
1191
1192 nbytes -= ret;
1193 buffer += ret;
1194 }
1195
1196 return total;
1197}
1198
1199wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
1200{
1201 struct
1202 {
1203 unsigned char sig[4];
1204 unsigned char len[4];
1205 } msg;
1206
1207 wxSocketWriteGuard write(this);
1208
1209 wxSocketWaitModeChanger changeFlags(this, (wxSOCKET_WAITALL|wxSOCKET_WAITALL_WRITE));
1210
1211 msg.sig[0] = (unsigned char) 0xad;
1212 msg.sig[1] = (unsigned char) 0xde;
1213 msg.sig[2] = (unsigned char) 0xed;
1214 msg.sig[3] = (unsigned char) 0xfe;
1215
1216 msg.len[0] = (unsigned char) (nbytes & 0xff);
1217 msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
1218 msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
1219 msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
1220
1221 bool ok = false;
1222 if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg) )
1223 {
1224 m_lcount_write = DoWrite(buffer, nbytes);
1225 m_lcount = m_lcount_write;
1226 if ( m_lcount_write == nbytes )
1227 {
1228 msg.sig[0] = (unsigned char) 0xed;
1229 msg.sig[1] = (unsigned char) 0xfe;
1230 msg.sig[2] = (unsigned char) 0xad;
1231 msg.sig[3] = (unsigned char) 0xde;
1232 msg.len[0] =
1233 msg.len[1] =
1234 msg.len[2] =
1235 msg.len[3] = (char) 0;
1236
1237 if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg))
1238 ok = true;
1239 }
1240 }
1241
1242 if ( !ok )
1243 SetError(wxSOCKET_IOERR);
1244
1245 return *this;
1246}
1247
1248wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
1249{
1250 if (nbytes != 0)
1251 Pushback(buffer, nbytes);
1252
1253 SetError(wxSOCKET_NOERROR);
1254 m_lcount = nbytes;
1255
1256 return *this;
1257}
1258
1259wxSocketBase& wxSocketBase::Discard()
1260{
1261 char *buffer = new char[MAX_DISCARD_SIZE];
1262 wxUint32 ret;
1263 wxUint32 total = 0;
1264
1265 wxSocketReadGuard read(this);
1266
1267 wxSocketWaitModeChanger changeFlags(this, wxSOCKET_NOWAIT);
1268
1269 do
1270 {
1271 ret = DoRead(buffer, MAX_DISCARD_SIZE);
1272 total += ret;
1273 }
1274 while (ret == MAX_DISCARD_SIZE);
1275
1276 delete[] buffer;
1277 m_lcount = total;
1278 SetError(wxSOCKET_NOERROR);
1279
1280 return *this;
1281}
1282
1283// --------------------------------------------------------------------------
1284// Wait functions
1285// --------------------------------------------------------------------------
1286
1287/*
1288 This function will check for the events specified in the flags parameter,
1289 and it will return a mask indicating which operations can be performed.
1290 */
1291wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags,
1292 const timeval *timeout)
1293{
1294 if ( m_fd == INVALID_SOCKET )
1295 return (wxSOCKET_LOST_FLAG & flags);
1296
1297 struct timeval tv;
1298 if ( timeout )
1299 tv = *timeout;
1300 else
1301 tv.tv_sec = tv.tv_usec = 0;
1302
1303 // prepare the FD sets, passing NULL for the one(s) we don't use
1304 fd_set
1305 readfds, *preadfds = NULL,
1306 writefds, *pwritefds = NULL,
1307 exceptfds; // always want to know about errors
1308
1309 if ( flags & wxSOCKET_INPUT_FLAG )
1310 preadfds = &readfds;
1311
1312 if ( flags & wxSOCKET_OUTPUT_FLAG )
1313 pwritefds = &writefds;
1314
1315 // When using non-blocking connect() the client socket becomes connected
1316 // (successfully or not) when it becomes writable but when using
1317 // non-blocking accept() the server socket becomes connected when it
1318 // becomes readable.
1319 if ( flags & wxSOCKET_CONNECTION_FLAG )
1320 {
1321 if ( m_server )
1322 preadfds = &readfds;
1323 else
1324 pwritefds = &writefds;
1325 }
1326
1327 if ( preadfds )
1328 {
1329 wxFD_ZERO(preadfds);
1330 wxFD_SET(m_fd, preadfds);
1331 }
1332
1333 if ( pwritefds )
1334 {
1335 wxFD_ZERO(pwritefds);
1336 wxFD_SET(m_fd, pwritefds);
1337 }
1338
1339 wxFD_ZERO(&exceptfds);
1340 wxFD_SET(m_fd, &exceptfds);
1341
1342 const int rc = select(m_fd + 1, preadfds, pwritefds, &exceptfds, &tv);
1343
1344 // check for errors first
1345 if ( rc == -1 || wxFD_ISSET(m_fd, &exceptfds) )
1346 {
1347 m_establishing = false;
1348
1349 return wxSOCKET_LOST_FLAG & flags;
1350 }
1351
1352 if ( rc == 0 )
1353 return 0;
1354
1355 wxASSERT_MSG( rc == 1, "unexpected select() return value" );
1356
1357 wxSocketEventFlags detected = 0;
1358 if ( preadfds && wxFD_ISSET(m_fd, preadfds) )
1359 detected |= wxSOCKET_INPUT_FLAG;
1360
1361 if ( pwritefds && wxFD_ISSET(m_fd, pwritefds) )
1362 {
1363 // check for the case of non-blocking connect()
1364 if ( m_establishing && !m_server )
1365 {
1366 int error;
1367 SOCKOPTLEN_T len = sizeof(error);
1368 m_establishing = false;
1369 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1370
1371 if ( error )
1372 detected = wxSOCKET_LOST_FLAG;
1373 else
1374 detected |= wxSOCKET_CONNECTION_FLAG;
1375 }
1376 else // not called to get non-blocking connect() status
1377 {
1378 detected |= wxSOCKET_OUTPUT_FLAG;
1379 }
1380 }
1381
1382 return detected & flags;
1383}
1384
1385int
1386wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
1387{
1388 // Use either the provided timeout or the default timeout value associated
1389 // with this socket.
1390 //
1391 // TODO: allow waiting forever, see #9443
1392 const long timeout = seconds == -1 ? m_timeout * 1000
1393 : seconds * 1000 + milliseconds;
1394
1395 return DoWait(timeout, flags);
1396}
1397
1398int
1399wxSocketBase::DoWait(long timeout, wxSocketEventFlags flags)
1400{
1401 wxCHECK_MSG( m_impl, -1, "can't wait on invalid socket" );
1402
1403 // we're never going to become ready in a TCP client if we're not connected
1404 // any more (OTOH a server can call this to precisely wait for a connection
1405 // so do wait for it in this case and UDP client is never "connected")
1406 if ( !m_impl->IsServer() &&
1407 m_impl->m_stream && !m_connected && !m_establishing )
1408 return -1;
1409
1410 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1411 m_interrupt = false;
1412
1413
1414 const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
1415
1416 // Get the active event loop which we'll use for the message dispatching
1417 // when running in the main thread unless this was explicitly disabled by
1418 // setting wxSOCKET_BLOCK flag
1419 wxEventLoopBase *eventLoop;
1420 if ( !(m_flags & wxSOCKET_BLOCK) && wxIsMainThread() )
1421 {
1422 eventLoop = wxEventLoop::GetActive();
1423 }
1424 else // in worker thread
1425 {
1426 // We never dispatch messages from threads other than the main one.
1427 eventLoop = NULL;
1428 }
1429
1430 // Make sure the events we're interested in are enabled before waiting for
1431 // them: this is really necessary here as otherwise this could happen:
1432 // 1. DoRead(wxSOCKET_WAITALL) is called
1433 // 2. There is nothing to read so DoWait(wxSOCKET_INPUT_FLAG) is called
1434 // 3. Some, but not all data appears, wxSocketImplUnix::OnReadWaiting()
1435 // is called and wxSOCKET_INPUT_FLAG events are disabled in it
1436 // 4. Because of wxSOCKET_WAITALL we call DoWait() again but the events
1437 // are still disabled and we block forever
1438 //
1439 // More elegant solution would be nice but for now simply re-enabling the
1440 // events here will do
1441 m_impl->ReenableEvents(flags & (wxSOCKET_INPUT_FLAG | wxSOCKET_OUTPUT_FLAG));
1442
1443
1444 // Wait until we receive the event we're waiting for or the timeout expires
1445 // (but note that we always execute the loop at least once, even if timeout
1446 // is 0 as this is used for polling)
1447 int rc = 0;
1448 for ( bool firstTime = true; !m_interrupt; firstTime = false )
1449 {
1450 long timeLeft = wxMilliClockToLong(timeEnd - wxGetLocalTimeMillis());
1451 if ( timeLeft < 0 )
1452 {
1453 if ( !firstTime )
1454 break; // timed out
1455
1456 timeLeft = 0;
1457 }
1458
1459 wxSocketEventFlags events;
1460 if ( eventLoop )
1461 {
1462 // reset them before starting to wait
1463 m_eventsgot = 0;
1464
1465 eventLoop->DispatchTimeout(timeLeft);
1466
1467 events = m_eventsgot;
1468 }
1469 else // no event loop or waiting in another thread
1470 {
1471 // as explained below, we should always check for wxSOCKET_LOST_FLAG
1472 timeval tv;
1473 SetTimeValFromMS(tv, timeLeft);
1474 events = m_impl->Select(flags | wxSOCKET_LOST_FLAG, &tv);
1475 }
1476
1477 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1478 // it, as continuing to wait for anything else after getting it is
1479 // pointless
1480 if ( events & wxSOCKET_LOST_FLAG )
1481 {
1482 m_connected = false;
1483 m_establishing = false;
1484 rc = -1;
1485 break;
1486 }
1487
1488 // otherwise mask out the bits we're not interested in
1489 events &= flags;
1490
1491 // Incoming connection (server) or connection established (client)?
1492 if ( events & wxSOCKET_CONNECTION_FLAG )
1493 {
1494 m_connected = true;
1495 m_establishing = false;
1496 rc = true;
1497 break;
1498 }
1499
1500 // Data available or output buffer ready?
1501 if ( (events & wxSOCKET_INPUT_FLAG) || (events & wxSOCKET_OUTPUT_FLAG) )
1502 {
1503 rc = true;
1504 break;
1505 }
1506 }
1507
1508 return rc;
1509}
1510
1511bool wxSocketBase::Wait(long seconds, long milliseconds)
1512{
1513 return DoWait(seconds, milliseconds,
1514 wxSOCKET_INPUT_FLAG |
1515 wxSOCKET_OUTPUT_FLAG |
1516 wxSOCKET_CONNECTION_FLAG) != 0;
1517}
1518
1519bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
1520{
1521 // Check pushback buffer before entering DoWait
1522 if ( m_unread )
1523 return true;
1524
1525 // Check if the socket is not already ready for input, if it is, there is
1526 // no need to start waiting for it (worse, we'll actually never get a
1527 // notification about the socket becoming ready if it is already under
1528 // Windows)
1529 if ( m_impl->Select(wxSOCKET_INPUT_FLAG) )
1530 return true;
1531
1532 return DoWait(seconds, milliseconds, wxSOCKET_INPUT_FLAG) != 0;
1533}
1534
1535
1536bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
1537{
1538 if ( m_impl->Select(wxSOCKET_OUTPUT_FLAG) )
1539 return true;
1540
1541 return DoWait(seconds, milliseconds, wxSOCKET_OUTPUT_FLAG) != 0;
1542}
1543
1544bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
1545{
1546 return DoWait(seconds, milliseconds, wxSOCKET_LOST_FLAG) == -1;
1547}
1548
1549// --------------------------------------------------------------------------
1550// Miscellaneous
1551// --------------------------------------------------------------------------
1552
1553//
1554// Get local or peer address
1555//
1556
1557bool wxSocketBase::GetPeer(wxSockAddress& addr) const
1558{
1559 wxCHECK_MSG( m_impl, false, "invalid socket" );
1560
1561 const wxSockAddressImpl& peer = m_impl->GetPeer();
1562 if ( !peer.IsOk() )
1563 return false;
1564
1565 addr.SetAddress(peer);
1566
1567 return true;
1568}
1569
1570bool wxSocketBase::GetLocal(wxSockAddress& addr) const
1571{
1572 wxCHECK_MSG( m_impl, false, "invalid socket" );
1573
1574 const wxSockAddressImpl& local = m_impl->GetLocal();
1575 if ( !local.IsOk() )
1576 return false;
1577
1578 addr.SetAddress(local);
1579
1580 return true;
1581}
1582
1583//
1584// Save and restore socket state
1585//
1586
1587void wxSocketBase::SaveState()
1588{
1589 wxSocketState *state;
1590
1591 state = new wxSocketState();
1592
1593 state->m_flags = m_flags;
1594 state->m_notify = m_notify;
1595 state->m_eventmask = m_eventmask;
1596 state->m_clientData = m_clientData;
1597
1598 m_states.Append(state);
1599}
1600
1601void wxSocketBase::RestoreState()
1602{
1603 wxList::compatibility_iterator node;
1604 wxSocketState *state;
1605
1606 node = m_states.GetLast();
1607 if (!node)
1608 return;
1609
1610 state = (wxSocketState *)node->GetData();
1611
1612 m_flags = state->m_flags;
1613 m_notify = state->m_notify;
1614 m_eventmask = state->m_eventmask;
1615 m_clientData = state->m_clientData;
1616
1617 m_states.Erase(node);
1618 delete state;
1619}
1620
1621//
1622// Timeout and flags
1623//
1624
1625void wxSocketBase::SetTimeout(long seconds)
1626{
1627 m_timeout = seconds;
1628
1629 if (m_impl)
1630 m_impl->SetTimeout(m_timeout * 1000);
1631}
1632
1633void wxSocketBase::SetFlags(wxSocketFlags flags)
1634{
1635 // Do some sanity checking on the flags used: not all values can be used
1636 // together.
1637 wxASSERT_MSG( !(flags & wxSOCKET_NOWAIT) ||
1638 !(flags & (wxSOCKET_WAITALL | wxSOCKET_BLOCK)),
1639 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1640 "wxSOCKET_NOWAIT doesn't make sense" );
1641
1642 m_flags = flags;
1643}
1644
1645
1646// --------------------------------------------------------------------------
1647// Event handling
1648// --------------------------------------------------------------------------
1649
1650void wxSocketBase::OnRequest(wxSocketNotify notification)
1651{
1652 wxSocketEventFlags flag = 0;
1653 switch ( notification )
1654 {
1655 case wxSOCKET_INPUT:
1656 flag = wxSOCKET_INPUT_FLAG;
1657 break;
1658
1659 case wxSOCKET_OUTPUT:
1660 flag = wxSOCKET_OUTPUT_FLAG;
1661 break;
1662
1663 case wxSOCKET_CONNECTION:
1664 flag = wxSOCKET_CONNECTION_FLAG;
1665
1666 // we're now successfully connected
1667 m_connected = true;
1668 m_establishing = false;
1669
1670 // error was previously set to wxSOCKET_WOULDBLOCK, but this is not
1671 // the case any longer
1672 SetError(wxSOCKET_NOERROR);
1673 break;
1674
1675 case wxSOCKET_LOST:
1676 flag = wxSOCKET_LOST_FLAG;
1677
1678 // if we lost the connection the socket is now closed and not
1679 // connected any more
1680 m_connected = false;
1681 m_closed = true;
1682 break;
1683
1684 default:
1685 wxFAIL_MSG( "unknown wxSocket notification" );
1686 }
1687
1688 // remember the events which were generated for this socket, we're going to
1689 // use this in DoWait()
1690 m_eventsgot |= flag;
1691
1692 // send the wx event if enabled and we're interested in it
1693 if ( m_notify && (m_eventmask & flag) && m_handler )
1694 {
1695 // don't generate the events when we're inside DoWait() called from our
1696 // own code as we are going to consume the data that has just become
1697 // available ourselves and the user code won't see it at all
1698 if ( (notification == wxSOCKET_INPUT && m_reading) ||
1699 (notification == wxSOCKET_OUTPUT && m_writing) )
1700 {
1701 return;
1702 }
1703
1704 wxSocketEvent event(m_id);
1705 event.m_event = notification;
1706 event.m_clientData = m_clientData;
1707 event.SetEventObject(this);
1708
1709 m_handler->AddPendingEvent(event);
1710 }
1711}
1712
1713void wxSocketBase::Notify(bool notify)
1714{
1715 m_notify = notify;
1716}
1717
1718void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1719{
1720 m_eventmask = flags;
1721}
1722
1723void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1724{
1725 m_handler = &handler;
1726 m_id = id;
1727}
1728
1729// --------------------------------------------------------------------------
1730// Pushback buffer
1731// --------------------------------------------------------------------------
1732
1733void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1734{
1735 if (!size) return;
1736
1737 if (m_unread == NULL)
1738 m_unread = malloc(size);
1739 else
1740 {
1741 void *tmp;
1742
1743 tmp = malloc(m_unrd_size + size);
1744 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1745 free(m_unread);
1746
1747 m_unread = tmp;
1748 }
1749
1750 m_unrd_size += size;
1751
1752 memcpy(m_unread, buffer, size);
1753}
1754
1755wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1756{
1757 wxCHECK_MSG( buffer, 0, "NULL buffer" );
1758
1759 if (!m_unrd_size)
1760 return 0;
1761
1762 if (size > (m_unrd_size-m_unrd_cur))
1763 size = m_unrd_size-m_unrd_cur;
1764
1765 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1766
1767 if (!peek)
1768 {
1769 m_unrd_cur += size;
1770 if (m_unrd_size == m_unrd_cur)
1771 {
1772 free(m_unread);
1773 m_unread = NULL;
1774 m_unrd_size = 0;
1775 m_unrd_cur = 0;
1776 }
1777 }
1778
1779 return size;
1780}
1781
1782
1783// ==========================================================================
1784// wxSocketServer
1785// ==========================================================================
1786
1787// --------------------------------------------------------------------------
1788// Ctor
1789// --------------------------------------------------------------------------
1790
1791wxSocketServer::wxSocketServer(const wxSockAddress& addr,
1792 wxSocketFlags flags)
1793 : wxSocketBase(flags, wxSOCKET_SERVER)
1794{
1795 wxLogTrace( wxTRACE_Socket, wxT("Opening wxSocketServer") );
1796
1797 wxSocketManager * const manager = wxSocketManager::Get();
1798 m_impl = manager ? manager->CreateSocket(*this) : NULL;
1799
1800 if (!m_impl)
1801 {
1802 wxLogTrace( wxTRACE_Socket, wxT("*** Failed to create m_impl") );
1803 return;
1804 }
1805
1806 // Setup the socket as server
1807 m_impl->SetLocal(addr.GetAddress());
1808
1809 if (GetFlags() & wxSOCKET_REUSEADDR) {
1810 m_impl->SetReusable();
1811 }
1812 if (GetFlags() & wxSOCKET_BROADCAST) {
1813 m_impl->SetBroadcast();
1814 }
1815 if (GetFlags() & wxSOCKET_NOBIND) {
1816 m_impl->DontDoBind();
1817 }
1818
1819 if (m_impl->CreateServer() != wxSOCKET_NOERROR)
1820 {
1821 wxDELETE(m_impl);
1822
1823 wxLogTrace( wxTRACE_Socket, wxT("*** CreateServer() failed") );
1824 return;
1825 }
1826
1827 // Notice that we need a cast as SOCKET is 64 bit under Win64 and that the
1828 // cast is safe because a SOCKET is a handle and so limited to 32 (or,
1829 // actually, even 24) bit values anyhow.
1830 wxLogTrace( wxTRACE_Socket, wxT("wxSocketServer on fd %u"),
1831 static_cast<unsigned>(m_impl->m_fd) );
1832}
1833
1834// --------------------------------------------------------------------------
1835// Accept
1836// --------------------------------------------------------------------------
1837
1838bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1839{
1840 if ( !m_impl || (m_impl->m_fd == INVALID_SOCKET) || !m_impl->IsServer() )
1841 {
1842 wxFAIL_MSG( "can only be called for a valid server socket" );
1843
1844 SetError(wxSOCKET_INVSOCK);
1845
1846 return false;
1847 }
1848
1849 if ( wait )
1850 {
1851 // wait until we get a connection
1852 if ( !m_impl->SelectWithTimeout(wxSOCKET_INPUT_FLAG) )
1853 {
1854 SetError(wxSOCKET_TIMEDOUT);
1855
1856 return false;
1857 }
1858 }
1859
1860 sock.m_impl = m_impl->Accept(sock);
1861
1862 if ( !sock.m_impl )
1863 {
1864 SetError(m_impl->GetLastError());
1865
1866 return false;
1867 }
1868
1869 sock.m_type = wxSOCKET_BASE;
1870 sock.m_connected = true;
1871
1872 return true;
1873}
1874
1875wxSocketBase *wxSocketServer::Accept(bool wait)
1876{
1877 wxSocketBase* sock = new wxSocketBase();
1878
1879 sock->SetFlags(m_flags);
1880
1881 if (!AcceptWith(*sock, wait))
1882 {
1883 sock->Destroy();
1884 sock = NULL;
1885 }
1886
1887 return sock;
1888}
1889
1890bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1891{
1892 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG) == 1;
1893}
1894
1895bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1896{
1897 wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
1898
1899 SOCKOPTLEN_T lenreal = *optlen;
1900 if ( getsockopt(m_impl->m_fd, level, optname,
1901 static_cast<char *>(optval), &lenreal) != 0 )
1902 return false;
1903
1904 *optlen = lenreal;
1905
1906 return true;
1907}
1908
1909bool
1910wxSocketBase::SetOption(int level, int optname, const void *optval, int optlen)
1911{
1912 wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
1913
1914 return setsockopt(m_impl->m_fd, level, optname,
1915 static_cast<const char *>(optval), optlen) == 0;
1916}
1917
1918bool wxSocketBase::SetLocal(const wxIPV4address& local)
1919{
1920 m_localAddress = local;
1921
1922 return true;
1923}
1924
1925// ==========================================================================
1926// wxSocketClient
1927// ==========================================================================
1928
1929// --------------------------------------------------------------------------
1930// Ctor and dtor
1931// --------------------------------------------------------------------------
1932
1933wxSocketClient::wxSocketClient(wxSocketFlags flags)
1934 : wxSocketBase(flags, wxSOCKET_CLIENT)
1935{
1936 m_initialRecvBufferSize =
1937 m_initialSendBufferSize = -1;
1938}
1939
1940// --------------------------------------------------------------------------
1941// Connect
1942// --------------------------------------------------------------------------
1943
1944bool wxSocketClient::DoConnect(const wxSockAddress& remote,
1945 const wxSockAddress* local,
1946 bool wait)
1947{
1948 if ( m_impl )
1949 {
1950 // Shutdown and destroy the old socket
1951 Close();
1952 delete m_impl;
1953 }
1954
1955 m_connected = false;
1956 m_establishing = false;
1957
1958 // Create and set up the new one
1959 wxSocketManager * const manager = wxSocketManager::Get();
1960 m_impl = manager ? manager->CreateSocket(*this) : NULL;
1961 if ( !m_impl )
1962 return false;
1963
1964 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1965 if (GetFlags() & wxSOCKET_REUSEADDR)
1966 m_impl->SetReusable();
1967 if (GetFlags() & wxSOCKET_BROADCAST)
1968 m_impl->SetBroadcast();
1969 if (GetFlags() & wxSOCKET_NOBIND)
1970 m_impl->DontDoBind();
1971
1972 // Bind to the local IP address and port, when provided or if one had been
1973 // set before
1974 if ( !local && m_localAddress.GetAddress().IsOk() )
1975 local = &m_localAddress;
1976
1977 if ( local )
1978 m_impl->SetLocal(local->GetAddress());
1979
1980 m_impl->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
1981
1982 m_impl->SetPeer(remote.GetAddress());
1983
1984 // Finally do create the socket and connect to the peer
1985 const wxSocketError err = m_impl->CreateClient(wait);
1986
1987 if ( err != wxSOCKET_NOERROR )
1988 {
1989 if ( err == wxSOCKET_WOULDBLOCK )
1990 {
1991 wxASSERT_MSG( !wait, "shouldn't get this for blocking connect" );
1992
1993 m_establishing = true;
1994 }
1995
1996 return false;
1997 }
1998
1999 m_connected = true;
2000 return true;
2001}
2002
2003bool wxSocketClient::Connect(const wxSockAddress& remote, bool wait)
2004{
2005 return DoConnect(remote, NULL, wait);
2006}
2007
2008bool wxSocketClient::Connect(const wxSockAddress& remote,
2009 const wxSockAddress& local,
2010 bool wait)
2011{
2012 return DoConnect(remote, &local, wait);
2013}
2014
2015bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
2016{
2017 if ( m_connected )
2018 {
2019 // this happens if the initial attempt to connect succeeded without
2020 // blocking
2021 return true;
2022 }
2023
2024 wxCHECK_MSG( m_establishing && m_impl, false,
2025 "No connection establishment attempt in progress" );
2026
2027 // notice that we return true even if DoWait() returned -1, i.e. if an
2028 // error occurred and connection was lost: this is intentional as we should
2029 // return false only if timeout expired without anything happening
2030 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG) != 0;
2031}
2032
2033// ==========================================================================
2034// wxDatagramSocket
2035// ==========================================================================
2036
2037wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
2038 wxSocketFlags flags )
2039 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
2040{
2041 // Create the socket
2042 wxSocketManager * const manager = wxSocketManager::Get();
2043 m_impl = manager ? manager->CreateSocket(*this) : NULL;
2044
2045 if (!m_impl)
2046 return;
2047
2048 // Setup the socket as non connection oriented
2049 m_impl->SetLocal(addr.GetAddress());
2050 if (flags & wxSOCKET_REUSEADDR)
2051 {
2052 m_impl->SetReusable();
2053 }
2054 if (GetFlags() & wxSOCKET_BROADCAST)
2055 {
2056 m_impl->SetBroadcast();
2057 }
2058 if (GetFlags() & wxSOCKET_NOBIND)
2059 {
2060 m_impl->DontDoBind();
2061 }
2062
2063 if ( m_impl->CreateUDP() != wxSOCKET_NOERROR )
2064 {
2065 wxDELETE(m_impl);
2066 return;
2067 }
2068
2069 // Initialize all stuff
2070 m_connected = false;
2071 m_establishing = false;
2072}
2073
2074wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
2075 void* buf,
2076 wxUint32 nBytes )
2077{
2078 Read(buf, nBytes);
2079 GetPeer(addr);
2080 return (*this);
2081}
2082
2083wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
2084 const void* buf,
2085 wxUint32 nBytes )
2086{
2087 wxASSERT_MSG( m_impl, wxT("Socket not initialised") );
2088
2089 m_impl->SetPeer(addr.GetAddress());
2090 Write(buf, nBytes);
2091 return (*this);
2092}
2093
2094// ==========================================================================
2095// wxSocketModule
2096// ==========================================================================
2097
2098class wxSocketModule : public wxModule
2099{
2100public:
2101 virtual bool OnInit()
2102 {
2103 // wxSocketBase will call Initialize() itself only if sockets are
2104 // really used, don't do it from here
2105 return true;
2106 }
2107
2108 virtual void OnExit()
2109 {
2110 if ( wxSocketBase::IsInitialized() )
2111 wxSocketBase::Shutdown();
2112 }
2113
2114private:
2115 DECLARE_DYNAMIC_CLASS(wxSocketModule)
2116};
2117
2118IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
2119
2120#if defined(wxUSE_SELECT_DISPATCHER) && wxUSE_SELECT_DISPATCHER
2121// NOTE: we need to force linking against socketiohandler.cpp otherwise in
2122// static builds of wxWidgets the ManagerSetter::ManagerSetter ctor
2123// contained there wouldn't be ever called
2124wxFORCE_LINK_MODULE( socketiohandler )
2125#endif
2126
2127// same for ManagerSetter in the MSW file
2128#ifdef __WINDOWS__
2129 wxFORCE_LINK_MODULE( mswsocket )
2130#endif
2131
2132// and for OSXManagerSetter in the OS X one
2133#ifdef __WXOSX__
2134 wxFORCE_LINK_MODULE( osxsocket )
2135#endif
2136
2137#endif // wxUSE_SOCKETS