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