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