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