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