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