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