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