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