]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/socket.cpp
ensure that WIN32 is defined, winsock2.h relies on it being defined and fails in...
[wxWidgets.git] / src / common / socket.cpp
... / ...
CommitLineData
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"
73WX_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
88IMPLEMENT_CLASS(wxSocketBase, wxObject)
89IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
90IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
91IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
92IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
93
94// ----------------------------------------------------------------------------
95// private functions
96// ----------------------------------------------------------------------------
97
98namespace
99{
100
101void 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
113class wxSocketState : public wxObject
114{
115public:
116 wxSocketFlags m_flags;
117 wxSocketEventFlags m_eventmask;
118 bool m_notify;
119 void *m_clientData;
120
121public:
122 wxSocketState() : wxObject() {}
123
124 DECLARE_NO_COPY_CLASS(wxSocketState)
125};
126
127// ============================================================================
128// wxSocketManager
129// ============================================================================
130
131wxSocketManager *wxSocketManager::ms_manager = NULL;
132
133/* static */
134void 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 */
142void 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
175wxSocketImpl::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
193wxSocketImpl::~wxSocketImpl()
194{
195 if ( m_fd != INVALID_SOCKET )
196 Shutdown();
197}
198
199bool 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
216void 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
243wxSocketError 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
256wxSocketError 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
297wxSocketError 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
354wxSocketError 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
387wxSocketImpl *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
406void 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 */
419void 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 */
432void wxSocketImpl::SetTimeout(unsigned long millis)
433{
434 SetTimeValFromMS(m_timeout, millis);
435}
436
437void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event)
438{
439 m_wxsocket->OnRequest(event);
440}
441
442/* Address handling */
443wxSocketError 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
463wxSocketError 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
476const 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
501int 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
522int 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
531int 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
550int 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
565int 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
582int 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
608size_t wxSocketBase::m_countInit = 0;
609
610bool wxSocketBase::IsInitialized()
611{
612 return m_countInit > 0;
613}
614
615bool 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
631void 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
648void 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
685wxSocketBase::wxSocketBase()
686{
687 Init();
688}
689
690wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
691{
692 Init();
693
694 SetFlags(flags);
695
696 m_type = type;
697}
698
699wxSocketBase::~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
719bool 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
752void wxSocketBase::SetError(wxSocketError error)
753{
754 m_impl->m_error = error;
755}
756
757wxSocketError 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}
768bool wxSocketBase::Close()
769{
770 // Interrupt pending waits
771 InterruptWait();
772
773 if (m_impl)
774 m_impl->Shutdown();
775
776 m_connected = false;
777 m_establishing = false;
778 return true;
779}
780
781wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
782{
783 // Mask read events
784 m_reading = true;
785
786 m_lcount = DoRead(buffer, nbytes);
787
788 // Allow read events from now on
789 m_reading = false;
790
791 return *this;
792}
793
794wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
795{
796 // We use pointer arithmetic here which doesn't work with void pointers.
797 char *buffer = static_cast<char *>(buffer_);
798
799 // Try the push back buffer first, even before checking whether the socket
800 // is valid to allow reading previously pushed back data from an already
801 // closed socket.
802 wxUint32 total = GetPushback(buffer, nbytes, false);
803 nbytes -= total;
804 buffer += total;
805
806 // If it's indeed closed or if read everything, there is nothing more to do.
807 if ( !m_impl || !nbytes )
808 return total;
809
810 wxCHECK_MSG( buffer, 0, "NULL buffer" );
811
812
813 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
814 // polling the socket and don't block at all.
815 if ( m_flags & wxSOCKET_NOWAIT )
816 {
817 int ret = m_impl->Read(buffer, nbytes);
818 if ( ret == -1 )
819 {
820 if ( m_impl->GetLastError() != wxSOCKET_WOULDBLOCK )
821 SetError(wxSOCKET_IOERR);
822 }
823 else // not an error, even if we didn't read anything
824 {
825 total += ret;
826 }
827 }
828 else // blocking socket
829 {
830 for ( ;; )
831 {
832 // Wait until socket becomes ready for reading
833 if ( !WaitForRead() )
834 break;
835
836 const int ret = m_impl->Read(buffer, nbytes);
837 if ( ret == 0 )
838 {
839 // for connection-oriented (e.g. TCP) sockets we can only read
840 // 0 bytes if the other end has been closed, and for
841 // connectionless ones (UDP) this flag doesn't make sense
842 // anyhow so we can set it to true too without doing any harm
843 m_closed = true;
844 break;
845 }
846
847 if ( ret == -1 )
848 {
849 SetError(wxSOCKET_IOERR);
850 break;
851 }
852
853 total += ret;
854
855 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
856 // something and we don't need to wait for all nbytes bytes to be
857 // read.
858 if ( !(m_flags & wxSOCKET_WAITALL) )
859 break;
860
861 // Otherwise continue reading until we do read everything.
862 nbytes -= ret;
863 if ( !nbytes )
864 break;
865
866 buffer += ret;
867 }
868
869 // it's an error to not read everything in wxSOCKET_WAITALL mode or to
870 // not read anything otherwise
871 if ( ((m_flags & wxSOCKET_WAITALL) && nbytes) || !total )
872 SetError(wxSOCKET_IOERR);
873 }
874
875 return total;
876}
877
878wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
879{
880 struct
881 {
882 unsigned char sig[4];
883 unsigned char len[4];
884 } msg;
885
886 // Mask read events
887 m_reading = true;
888
889 int old_flags = m_flags;
890 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
891
892 bool ok = false;
893 if ( DoRead(&msg, sizeof(msg)) == sizeof(msg) )
894 {
895 wxUint32 sig = (wxUint32)msg.sig[0];
896 sig |= (wxUint32)(msg.sig[1] << 8);
897 sig |= (wxUint32)(msg.sig[2] << 16);
898 sig |= (wxUint32)(msg.sig[3] << 24);
899
900 if ( sig == 0xfeeddead )
901 {
902 wxUint32 len = (wxUint32)msg.len[0];
903 len |= (wxUint32)(msg.len[1] << 8);
904 len |= (wxUint32)(msg.len[2] << 16);
905 len |= (wxUint32)(msg.len[3] << 24);
906
907 wxUint32 len2;
908 if (len > nbytes)
909 {
910 len2 = len - nbytes;
911 len = nbytes;
912 }
913 else
914 len2 = 0;
915
916 // Don't attempt to read if the msg was zero bytes long.
917 m_lcount = len ? DoRead(buffer, len) : 0;
918
919 if ( len2 )
920 {
921 char discard_buffer[MAX_DISCARD_SIZE];
922 long discard_len;
923
924 // NOTE: discarded bytes don't add to m_lcount.
925 do
926 {
927 discard_len = len2 > MAX_DISCARD_SIZE
928 ? MAX_DISCARD_SIZE
929 : len2;
930 discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
931 len2 -= (wxUint32)discard_len;
932 }
933 while ((discard_len > 0) && len2);
934 }
935
936 if ( !len2 && DoRead(&msg, sizeof(msg)) == sizeof(msg) )
937 {
938 sig = (wxUint32)msg.sig[0];
939 sig |= (wxUint32)(msg.sig[1] << 8);
940 sig |= (wxUint32)(msg.sig[2] << 16);
941 sig |= (wxUint32)(msg.sig[3] << 24);
942
943 if ( sig == 0xdeadfeed )
944 ok = true;
945 }
946 }
947 }
948
949 if ( !ok )
950 SetError(wxSOCKET_IOERR);
951
952 m_reading = false;
953 SetFlags(old_flags);
954
955 return *this;
956}
957
958wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
959{
960 // Mask read events
961 m_reading = true;
962
963 m_lcount = DoRead(buffer, nbytes);
964 Pushback(buffer, m_lcount);
965
966 // Allow read events again
967 m_reading = false;
968
969 return *this;
970}
971
972wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
973{
974 // Mask write events
975 m_writing = true;
976
977 m_lcount = DoWrite(buffer, nbytes);
978
979 // Allow write events again
980 m_writing = false;
981
982 return *this;
983}
984
985// This function is a mirror image of DoRead() except that it doesn't use the
986// push back buffer, please see comments there
987wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
988{
989 const char *buffer = static_cast<const char *>(buffer_);
990
991 // Return if there is nothing to read or the socket is (already?) closed.
992 if ( !m_impl || !nbytes )
993 return 0;
994
995 wxCHECK_MSG( buffer, 0, "NULL buffer" );
996
997 wxUint32 total = 0;
998 if ( m_flags & wxSOCKET_NOWAIT )
999 {
1000 const int ret = m_impl->Write(buffer, nbytes);
1001 if ( ret == -1 )
1002 {
1003 if ( m_impl->GetLastError() != wxSOCKET_WOULDBLOCK )
1004 SetError(wxSOCKET_IOERR);
1005 }
1006 else
1007 {
1008 total += ret;
1009 }
1010 }
1011 else // blocking socket
1012 {
1013 for ( ;; )
1014 {
1015 if ( !WaitForWrite() )
1016 break;
1017
1018 const int ret = m_impl->Write(buffer, nbytes);
1019 if ( ret == 0 )
1020 {
1021 m_closed = true;
1022 break;
1023 }
1024
1025 if ( ret == -1 )
1026 {
1027 SetError(wxSOCKET_IOERR);
1028 break;
1029 }
1030
1031 total += ret;
1032 if ( !(m_flags & wxSOCKET_WAITALL) )
1033 break;
1034
1035 nbytes -= ret;
1036 if ( !nbytes )
1037 break;
1038
1039 buffer += ret;
1040 }
1041
1042 if ( ((m_flags & wxSOCKET_WAITALL) && nbytes) || !total )
1043 SetError(wxSOCKET_IOERR);
1044 }
1045
1046 return total;
1047}
1048
1049wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
1050{
1051 struct
1052 {
1053 unsigned char sig[4];
1054 unsigned char len[4];
1055 } msg;
1056
1057 // Mask write events
1058 m_writing = true;
1059
1060 const int old_flags = m_flags;
1061 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
1062
1063 msg.sig[0] = (unsigned char) 0xad;
1064 msg.sig[1] = (unsigned char) 0xde;
1065 msg.sig[2] = (unsigned char) 0xed;
1066 msg.sig[3] = (unsigned char) 0xfe;
1067
1068 msg.len[0] = (unsigned char) (nbytes & 0xff);
1069 msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
1070 msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
1071 msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
1072
1073 bool ok = false;
1074 if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg) )
1075 {
1076 m_lcount = DoWrite(buffer, nbytes);
1077 if ( m_lcount == nbytes )
1078 {
1079 msg.sig[0] = (unsigned char) 0xed;
1080 msg.sig[1] = (unsigned char) 0xfe;
1081 msg.sig[2] = (unsigned char) 0xad;
1082 msg.sig[3] = (unsigned char) 0xde;
1083 msg.len[0] =
1084 msg.len[1] =
1085 msg.len[2] =
1086 msg.len[3] = (char) 0;
1087
1088 if ( DoWrite(&msg, sizeof(msg)) == sizeof(msg))
1089 ok = true;
1090 }
1091 }
1092
1093 if ( !ok )
1094 SetError(wxSOCKET_IOERR);
1095
1096 m_writing = false;
1097 SetFlags(old_flags);
1098
1099 return *this;
1100}
1101
1102wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
1103{
1104 if (nbytes != 0)
1105 Pushback(buffer, nbytes);
1106
1107 SetError(wxSOCKET_NOERROR);
1108 m_lcount = nbytes;
1109
1110 return *this;
1111}
1112
1113wxSocketBase& wxSocketBase::Discard()
1114{
1115 char *buffer = new char[MAX_DISCARD_SIZE];
1116 wxUint32 ret;
1117 wxUint32 total = 0;
1118
1119 // Mask read events
1120 m_reading = true;
1121
1122 const int old_flags = m_flags;
1123 SetFlags(wxSOCKET_NOWAIT);
1124
1125 do
1126 {
1127 ret = DoRead(buffer, MAX_DISCARD_SIZE);
1128 total += ret;
1129 }
1130 while (ret == MAX_DISCARD_SIZE);
1131
1132 delete[] buffer;
1133 m_lcount = total;
1134 SetError(wxSOCKET_NOERROR);
1135
1136 // Allow read events again
1137 m_reading = false;
1138
1139 SetFlags(old_flags);
1140
1141 return *this;
1142}
1143
1144// --------------------------------------------------------------------------
1145// Wait functions
1146// --------------------------------------------------------------------------
1147
1148/*
1149 This function will check for the events specified in the flags parameter,
1150 and it will return a mask indicating which operations can be performed.
1151 */
1152wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags,
1153 const timeval *timeout)
1154{
1155 if ( m_fd == INVALID_SOCKET )
1156 return (wxSOCKET_LOST_FLAG & flags);
1157
1158 struct timeval tv;
1159 if ( timeout )
1160 tv = *timeout;
1161 else
1162 tv.tv_sec = tv.tv_usec = 0;
1163
1164 // prepare the FD sets, passing NULL for the one(s) we don't use
1165 fd_set
1166 readfds, *preadfds = NULL,
1167 writefds, *pwritefds = NULL,
1168 exceptfds; // always want to know about errors
1169
1170 if ( flags & wxSOCKET_INPUT_FLAG )
1171 {
1172 preadfds = &readfds;
1173 wxFD_ZERO(preadfds);
1174 wxFD_SET(m_fd, preadfds);
1175 }
1176
1177 // when using non-blocking connect() the socket becomes connected
1178 // (successfully or not) when it becomes writable
1179 if ( flags & (wxSOCKET_OUTPUT_FLAG | wxSOCKET_CONNECTION_FLAG) )
1180 {
1181 pwritefds = &writefds;
1182 wxFD_ZERO(pwritefds);
1183 wxFD_SET(m_fd, pwritefds);
1184 }
1185
1186 wxFD_ZERO(&exceptfds);
1187 wxFD_SET(m_fd, &exceptfds);
1188
1189 const int rc = select(m_fd + 1, preadfds, pwritefds, &exceptfds, &tv);
1190
1191 // check for errors first
1192 if ( rc == -1 || wxFD_ISSET(m_fd, &exceptfds) )
1193 {
1194 m_establishing = false;
1195
1196 return wxSOCKET_LOST_FLAG & flags;
1197 }
1198
1199 if ( rc == 0 )
1200 return 0;
1201
1202 wxASSERT_MSG( rc == 1, "unexpected select() return value" );
1203
1204 wxSocketEventFlags detected = 0;
1205 if ( preadfds && wxFD_ISSET(m_fd, preadfds) )
1206 detected |= wxSOCKET_INPUT_FLAG;
1207
1208 if ( pwritefds && wxFD_ISSET(m_fd, pwritefds) )
1209 {
1210 // check for the case of non-blocking connect()
1211 if ( m_establishing && !m_server )
1212 {
1213 int error;
1214 SOCKOPTLEN_T len = sizeof(error);
1215 m_establishing = false;
1216 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1217
1218 if ( error )
1219 detected = wxSOCKET_LOST_FLAG;
1220 else
1221 detected |= wxSOCKET_CONNECTION_FLAG;
1222 }
1223 else // not called to get non-blocking connect() status
1224 {
1225 detected |= wxSOCKET_OUTPUT_FLAG;
1226 }
1227 }
1228
1229 return detected & flags;
1230}
1231
1232bool
1233wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
1234{
1235 wxCHECK_MSG( m_impl, false, "can't wait on invalid socket" );
1236
1237 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1238 m_interrupt = false;
1239
1240
1241 // Use either the provided timeout or the default timeout value associated
1242 // with this socket.
1243 //
1244 // TODO: allow waiting forever, see #9443
1245 const long timeout = seconds == -1 ? m_timeout * 1000
1246 : seconds * 1000 + milliseconds;
1247 const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
1248
1249 // Get the active event loop which we'll use for the message dispatching
1250 // when running in the main thread unless this was explicitly disabled by
1251 // setting wxSOCKET_BLOCK flag
1252 wxEventLoopBase *eventLoop;
1253 if ( !(m_flags & wxSOCKET_BLOCK) && wxIsMainThread() )
1254 {
1255 eventLoop = wxEventLoop::GetActive();
1256 }
1257 else // in worker thread
1258 {
1259 // We never dispatch messages from threads other than the main one.
1260 eventLoop = NULL;
1261 }
1262
1263 // Wait until we receive the event we're waiting for or the timeout expires
1264 // (but note that we always execute the loop at least once, even if timeout
1265 // is 0 as this is used for polling)
1266 bool gotEvent = false;
1267 for ( bool firstTime = true; !m_interrupt ; firstTime = false )
1268 {
1269 long timeLeft = wxMilliClockToLong(timeEnd - wxGetLocalTimeMillis());
1270 if ( timeLeft < 0 )
1271 {
1272 if ( !firstTime )
1273 break; // timed out
1274
1275 timeLeft = 0;
1276 }
1277
1278 // This function is only called if wxSOCKET_BLOCK flag was not used and
1279 // so we should dispatch the events if there is an event loop capable
1280 // of doing it.
1281 wxSocketEventFlags events;
1282 if ( eventLoop )
1283 {
1284 // reset them before starting to wait
1285 m_eventsgot = 0;
1286
1287 eventLoop->DispatchTimeout(timeLeft);
1288
1289 events = m_eventsgot;
1290 }
1291 else // no event loop or waiting in another thread
1292 {
1293 // as explained below, we should always check for wxSOCKET_LOST_FLAG
1294 timeval tv;
1295 SetTimeValFromMS(tv, timeLeft);
1296 events = m_impl->Select(flags | wxSOCKET_LOST_FLAG, &tv);
1297 }
1298
1299 // always check for wxSOCKET_LOST_FLAG, even if flags doesn't include
1300 // it, as continuing to wait for anything else after getting it is
1301 // pointless
1302 if ( events & wxSOCKET_LOST_FLAG )
1303 {
1304 m_connected = false;
1305 m_establishing = false;
1306 if ( flags & wxSOCKET_LOST_FLAG )
1307 gotEvent = true;
1308 break;
1309 }
1310
1311 // otherwise mask out the bits we're not interested in
1312 events &= flags;
1313
1314 // Incoming connection (server) or connection established (client)?
1315 if ( events & wxSOCKET_CONNECTION_FLAG )
1316 {
1317 m_connected = true;
1318 m_establishing = false;
1319 gotEvent = true;
1320 break;
1321 }
1322
1323 // Data available or output buffer ready?
1324 if ( (events & wxSOCKET_INPUT_FLAG) || (events & wxSOCKET_OUTPUT_FLAG) )
1325 {
1326 gotEvent = true;
1327 break;
1328 }
1329 }
1330
1331 return gotEvent;
1332}
1333
1334bool wxSocketBase::Wait(long seconds, long milliseconds)
1335{
1336 return DoWait(seconds, milliseconds,
1337 wxSOCKET_INPUT_FLAG |
1338 wxSOCKET_OUTPUT_FLAG |
1339 wxSOCKET_CONNECTION_FLAG |
1340 wxSOCKET_LOST_FLAG
1341 );
1342}
1343
1344bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
1345{
1346 // Check pushback buffer before entering DoWait
1347 if ( m_unread )
1348 return true;
1349
1350 // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
1351 // because of the semantics of WaitForRead: a return value of true means
1352 // that a Read call will return immediately, not that there is
1353 // actually data to read.
1354 return DoWait(seconds, milliseconds, wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
1355}
1356
1357
1358bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
1359{
1360 return DoWait(seconds, milliseconds, wxSOCKET_OUTPUT_FLAG | wxSOCKET_LOST_FLAG);
1361}
1362
1363bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
1364{
1365 return DoWait(seconds, milliseconds, wxSOCKET_LOST_FLAG);
1366}
1367
1368// --------------------------------------------------------------------------
1369// Miscellaneous
1370// --------------------------------------------------------------------------
1371
1372//
1373// Get local or peer address
1374//
1375
1376bool wxSocketBase::GetPeer(wxSockAddress& addr) const
1377{
1378 wxCHECK_MSG( m_impl, false, "invalid socket" );
1379
1380 const wxSockAddressImpl& peer = m_impl->GetPeer();
1381 if ( !peer.IsOk() )
1382 return false;
1383
1384 addr.SetAddress(peer);
1385
1386 return true;
1387}
1388
1389bool wxSocketBase::GetLocal(wxSockAddress& addr) const
1390{
1391 wxCHECK_MSG( m_impl, false, "invalid socket" );
1392
1393 const wxSockAddressImpl& local = m_impl->GetLocal();
1394 if ( !local.IsOk() )
1395 return false;
1396
1397 addr.SetAddress(local);
1398
1399 return true;
1400}
1401
1402//
1403// Save and restore socket state
1404//
1405
1406void wxSocketBase::SaveState()
1407{
1408 wxSocketState *state;
1409
1410 state = new wxSocketState();
1411
1412 state->m_flags = m_flags;
1413 state->m_notify = m_notify;
1414 state->m_eventmask = m_eventmask;
1415 state->m_clientData = m_clientData;
1416
1417 m_states.Append(state);
1418}
1419
1420void wxSocketBase::RestoreState()
1421{
1422 wxList::compatibility_iterator node;
1423 wxSocketState *state;
1424
1425 node = m_states.GetLast();
1426 if (!node)
1427 return;
1428
1429 state = (wxSocketState *)node->GetData();
1430
1431 m_flags = state->m_flags;
1432 m_notify = state->m_notify;
1433 m_eventmask = state->m_eventmask;
1434 m_clientData = state->m_clientData;
1435
1436 m_states.Erase(node);
1437 delete state;
1438}
1439
1440//
1441// Timeout and flags
1442//
1443
1444void wxSocketBase::SetTimeout(long seconds)
1445{
1446 m_timeout = seconds;
1447
1448 if (m_impl)
1449 m_impl->SetTimeout(m_timeout * 1000);
1450}
1451
1452void wxSocketBase::SetFlags(wxSocketFlags flags)
1453{
1454 // Do some sanity checking on the flags used: not all values can be used
1455 // together.
1456 wxASSERT_MSG( !(flags & wxSOCKET_NOWAIT) ||
1457 !(flags & (wxSOCKET_WAITALL | wxSOCKET_BLOCK)),
1458 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1459 "wxSOCKET_NOWAIT doesn't make sense" );
1460
1461 m_flags = flags;
1462}
1463
1464
1465// --------------------------------------------------------------------------
1466// Event handling
1467// --------------------------------------------------------------------------
1468
1469void wxSocketBase::OnRequest(wxSocketNotify notification)
1470{
1471 wxSocketEventFlags flag = 0;
1472 switch ( notification )
1473 {
1474 case wxSOCKET_INPUT:
1475 flag = wxSOCKET_INPUT_FLAG;
1476 break;
1477
1478 case wxSOCKET_OUTPUT:
1479 flag = wxSOCKET_OUTPUT_FLAG;
1480 break;
1481
1482 case wxSOCKET_CONNECTION:
1483 flag = wxSOCKET_CONNECTION_FLAG;
1484 break;
1485
1486 case wxSOCKET_LOST:
1487 flag = wxSOCKET_LOST_FLAG;
1488 break;
1489
1490 default:
1491 wxFAIL_MSG( "unknown wxSocket notification" );
1492 }
1493
1494 // if we lost the connection the socket is now closed
1495 if ( notification == wxSOCKET_LOST )
1496 m_closed = true;
1497
1498 // remember the events which were generated for this socket, we're going to
1499 // use this in DoWait()
1500 m_eventsgot |= flag;
1501
1502 // send the wx event if enabled and we're interested in it
1503 if ( m_notify && (m_eventmask & flag) && m_handler )
1504 {
1505 // If we are in the middle of a R/W operation, do not propagate events
1506 // to users. Also, filter 'late' events which are no longer valid.
1507 if ( notification == wxSOCKET_INPUT )
1508 {
1509 if ( m_reading || !m_impl->Select(wxSOCKET_INPUT_FLAG) )
1510 return;
1511 }
1512 else if ( notification == wxSOCKET_OUTPUT )
1513 {
1514 if ( m_writing || !m_impl->Select(wxSOCKET_OUTPUT_FLAG) )
1515 return;
1516 }
1517
1518 wxSocketEvent event(m_id);
1519 event.m_event = notification;
1520 event.m_clientData = m_clientData;
1521 event.SetEventObject(this);
1522
1523 m_handler->AddPendingEvent(event);
1524 }
1525}
1526
1527void wxSocketBase::Notify(bool notify)
1528{
1529 m_notify = notify;
1530}
1531
1532void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1533{
1534 m_eventmask = flags;
1535}
1536
1537void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1538{
1539 m_handler = &handler;
1540 m_id = id;
1541}
1542
1543// --------------------------------------------------------------------------
1544// Pushback buffer
1545// --------------------------------------------------------------------------
1546
1547void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1548{
1549 if (!size) return;
1550
1551 if (m_unread == NULL)
1552 m_unread = malloc(size);
1553 else
1554 {
1555 void *tmp;
1556
1557 tmp = malloc(m_unrd_size + size);
1558 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1559 free(m_unread);
1560
1561 m_unread = tmp;
1562 }
1563
1564 m_unrd_size += size;
1565
1566 memcpy(m_unread, buffer, size);
1567}
1568
1569wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1570{
1571 wxCHECK_MSG( buffer, 0, "NULL buffer" );
1572
1573 if (!m_unrd_size)
1574 return 0;
1575
1576 if (size > (m_unrd_size-m_unrd_cur))
1577 size = m_unrd_size-m_unrd_cur;
1578
1579 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1580
1581 if (!peek)
1582 {
1583 m_unrd_cur += size;
1584 if (m_unrd_size == m_unrd_cur)
1585 {
1586 free(m_unread);
1587 m_unread = NULL;
1588 m_unrd_size = 0;
1589 m_unrd_cur = 0;
1590 }
1591 }
1592
1593 return size;
1594}
1595
1596
1597// ==========================================================================
1598// wxSocketServer
1599// ==========================================================================
1600
1601// --------------------------------------------------------------------------
1602// Ctor
1603// --------------------------------------------------------------------------
1604
1605wxSocketServer::wxSocketServer(const wxSockAddress& addr,
1606 wxSocketFlags flags)
1607 : wxSocketBase(flags, wxSOCKET_SERVER)
1608{
1609 wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
1610
1611 m_impl = wxSocketImpl::Create(*this);
1612
1613 if (!m_impl)
1614 {
1615 wxLogTrace( wxTRACE_Socket, _T("*** Failed to create m_impl") );
1616 return;
1617 }
1618
1619 // Setup the socket as server
1620 m_impl->SetLocal(addr.GetAddress());
1621
1622 if (GetFlags() & wxSOCKET_REUSEADDR) {
1623 m_impl->SetReusable();
1624 }
1625 if (GetFlags() & wxSOCKET_BROADCAST) {
1626 m_impl->SetBroadcast();
1627 }
1628 if (GetFlags() & wxSOCKET_NOBIND) {
1629 m_impl->DontDoBind();
1630 }
1631
1632 if (m_impl->CreateServer() != wxSOCKET_NOERROR)
1633 {
1634 delete m_impl;
1635 m_impl = NULL;
1636
1637 wxLogTrace( wxTRACE_Socket, _T("*** CreateServer() failed") );
1638 return;
1639 }
1640
1641 wxLogTrace( wxTRACE_Socket, _T("wxSocketServer on fd %d"), m_impl->m_fd );
1642}
1643
1644// --------------------------------------------------------------------------
1645// Accept
1646// --------------------------------------------------------------------------
1647
1648bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1649{
1650 if ( !m_impl || (m_impl->m_fd == INVALID_SOCKET) || !m_impl->IsServer() )
1651 {
1652 wxFAIL_MSG( "can only be called for a valid server socket" );
1653
1654 SetError(wxSOCKET_INVSOCK);
1655
1656 return false;
1657 }
1658
1659 if ( wait )
1660 {
1661 // wait until we get a connection
1662 if ( !m_impl->SelectWithTimeout(wxSOCKET_INPUT_FLAG) )
1663 {
1664 SetError(wxSOCKET_TIMEDOUT);
1665
1666 return false;
1667 }
1668 }
1669
1670 sock.m_impl = m_impl->Accept(sock);
1671
1672 if ( !sock.m_impl )
1673 {
1674 SetError(m_impl->GetLastError());
1675
1676 return false;
1677 }
1678
1679 sock.m_type = wxSOCKET_BASE;
1680 sock.m_connected = true;
1681
1682 return true;
1683}
1684
1685wxSocketBase *wxSocketServer::Accept(bool wait)
1686{
1687 wxSocketBase* sock = new wxSocketBase();
1688
1689 sock->SetFlags(m_flags);
1690
1691 if (!AcceptWith(*sock, wait))
1692 {
1693 sock->Destroy();
1694 sock = NULL;
1695 }
1696
1697 return sock;
1698}
1699
1700bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1701{
1702 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG);
1703}
1704
1705bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1706{
1707 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1708
1709 SOCKOPTLEN_T lenreal = *optlen;
1710 if ( getsockopt(m_impl->m_fd, level, optname,
1711 static_cast<char *>(optval), &lenreal) != 0 )
1712 return false;
1713
1714 *optlen = lenreal;
1715
1716 return true;
1717}
1718
1719bool
1720wxSocketBase::SetOption(int level, int optname, const void *optval, int optlen)
1721{
1722 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1723
1724 return setsockopt(m_impl->m_fd, level, optname,
1725 static_cast<const char *>(optval), optlen) == 0;
1726}
1727
1728bool wxSocketBase::SetLocal(const wxIPV4address& local)
1729{
1730 m_localAddress = local;
1731
1732 return true;
1733}
1734
1735// ==========================================================================
1736// wxSocketClient
1737// ==========================================================================
1738
1739// --------------------------------------------------------------------------
1740// Ctor and dtor
1741// --------------------------------------------------------------------------
1742
1743wxSocketClient::wxSocketClient(wxSocketFlags flags)
1744 : wxSocketBase(flags, wxSOCKET_CLIENT)
1745{
1746 m_initialRecvBufferSize =
1747 m_initialSendBufferSize = -1;
1748}
1749
1750wxSocketClient::~wxSocketClient()
1751{
1752}
1753
1754// --------------------------------------------------------------------------
1755// Connect
1756// --------------------------------------------------------------------------
1757
1758bool wxSocketClient::DoConnect(const wxSockAddress& remote,
1759 const wxSockAddress* local,
1760 bool wait)
1761{
1762 if ( m_impl )
1763 {
1764 // Shutdown and destroy the old socket
1765 Close();
1766 delete m_impl;
1767 }
1768
1769 m_connected = false;
1770 m_establishing = false;
1771
1772 // Create and set up the new one
1773 m_impl = wxSocketImpl::Create(*this);
1774 if ( !m_impl )
1775 return false;
1776
1777 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1778 if (GetFlags() & wxSOCKET_REUSEADDR)
1779 m_impl->SetReusable();
1780 if (GetFlags() & wxSOCKET_BROADCAST)
1781 m_impl->SetBroadcast();
1782 if (GetFlags() & wxSOCKET_NOBIND)
1783 m_impl->DontDoBind();
1784
1785 // Bind to the local IP address and port, when provided or if one had been
1786 // set before
1787 if ( !local && m_localAddress.GetAddress().IsOk() )
1788 local = &m_localAddress;
1789
1790 if ( local )
1791 m_impl->SetLocal(local->GetAddress());
1792
1793 m_impl->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
1794
1795 m_impl->SetPeer(remote.GetAddress());
1796
1797 // Finally do create the socket and connect to the peer
1798 const wxSocketError err = m_impl->CreateClient(wait);
1799
1800 if ( err != wxSOCKET_NOERROR )
1801 {
1802 if ( err == wxSOCKET_WOULDBLOCK )
1803 {
1804 wxASSERT_MSG( !wait, "shouldn't get this for blocking connect" );
1805
1806 m_establishing = true;
1807 }
1808
1809 return false;
1810 }
1811
1812 m_connected = true;
1813 return true;
1814}
1815
1816bool wxSocketClient::Connect(const wxSockAddress& remote, bool wait)
1817{
1818 return DoConnect(remote, NULL, wait);
1819}
1820
1821bool wxSocketClient::Connect(const wxSockAddress& remote,
1822 const wxSockAddress& local,
1823 bool wait)
1824{
1825 return DoConnect(remote, &local, wait);
1826}
1827
1828bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1829{
1830 if ( m_connected )
1831 {
1832 // this happens if the initial attempt to connect succeeded without
1833 // blocking
1834 return true;
1835 }
1836
1837 wxCHECK_MSG( m_establishing && m_impl, false,
1838 "No connection establishment attempt in progress" );
1839
1840 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1841 // true if the connection establishment process is finished, whether it is
1842 // over because we successfully connected or because we were not able to
1843 // connect
1844 return DoWait(seconds, milliseconds,
1845 wxSOCKET_CONNECTION_FLAG | wxSOCKET_LOST_FLAG);
1846}
1847
1848// ==========================================================================
1849// wxDatagramSocket
1850// ==========================================================================
1851
1852wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
1853 wxSocketFlags flags )
1854 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
1855{
1856 // Create the socket
1857 m_impl = wxSocketImpl::Create(*this);
1858
1859 if (!m_impl)
1860 return;
1861
1862 // Setup the socket as non connection oriented
1863 m_impl->SetLocal(addr.GetAddress());
1864 if (flags & wxSOCKET_REUSEADDR)
1865 {
1866 m_impl->SetReusable();
1867 }
1868 if (GetFlags() & wxSOCKET_BROADCAST)
1869 {
1870 m_impl->SetBroadcast();
1871 }
1872 if (GetFlags() & wxSOCKET_NOBIND)
1873 {
1874 m_impl->DontDoBind();
1875 }
1876
1877 if ( m_impl->CreateUDP() != wxSOCKET_NOERROR )
1878 {
1879 delete m_impl;
1880 m_impl = NULL;
1881 return;
1882 }
1883
1884 // Initialize all stuff
1885 m_connected = false;
1886 m_establishing = false;
1887}
1888
1889wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
1890 void* buf,
1891 wxUint32 nBytes )
1892{
1893 Read(buf, nBytes);
1894 GetPeer(addr);
1895 return (*this);
1896}
1897
1898wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
1899 const void* buf,
1900 wxUint32 nBytes )
1901{
1902 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1903
1904 m_impl->SetPeer(addr.GetAddress());
1905 Write(buf, nBytes);
1906 return (*this);
1907}
1908
1909// ==========================================================================
1910// wxSocketModule
1911// ==========================================================================
1912
1913class wxSocketModule : public wxModule
1914{
1915public:
1916 virtual bool OnInit()
1917 {
1918 // wxSocketBase will call Initialize() itself only if sockets are
1919 // really used, don't do it from here
1920 return true;
1921 }
1922
1923 virtual void OnExit()
1924 {
1925 if ( wxSocketBase::IsInitialized() )
1926 wxSocketBase::Shutdown();
1927 }
1928
1929private:
1930 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1931};
1932
1933IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1934
1935#endif // wxUSE_SOCKETS