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