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