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