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