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