]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
remove m_use_events from Unix wxSocket implementation, we always need asynchronous...
[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 // Suppress 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 }
1544
1545 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1546 {
1547 m_eventmask = flags;
1548 }
1549
1550 void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1551 {
1552 m_handler = &handler;
1553 m_id = id;
1554 }
1555
1556 // --------------------------------------------------------------------------
1557 // Pushback buffer
1558 // --------------------------------------------------------------------------
1559
1560 void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1561 {
1562 if (!size) return;
1563
1564 if (m_unread == NULL)
1565 m_unread = malloc(size);
1566 else
1567 {
1568 void *tmp;
1569
1570 tmp = malloc(m_unrd_size + size);
1571 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1572 free(m_unread);
1573
1574 m_unread = tmp;
1575 }
1576
1577 m_unrd_size += size;
1578
1579 memcpy(m_unread, buffer, size);
1580 }
1581
1582 wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1583 {
1584 wxCHECK_MSG( buffer, 0, "NULL buffer" );
1585
1586 if (!m_unrd_size)
1587 return 0;
1588
1589 if (size > (m_unrd_size-m_unrd_cur))
1590 size = m_unrd_size-m_unrd_cur;
1591
1592 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1593
1594 if (!peek)
1595 {
1596 m_unrd_cur += size;
1597 if (m_unrd_size == m_unrd_cur)
1598 {
1599 free(m_unread);
1600 m_unread = NULL;
1601 m_unrd_size = 0;
1602 m_unrd_cur = 0;
1603 }
1604 }
1605
1606 return size;
1607 }
1608
1609
1610 // ==========================================================================
1611 // wxSocketServer
1612 // ==========================================================================
1613
1614 // --------------------------------------------------------------------------
1615 // Ctor
1616 // --------------------------------------------------------------------------
1617
1618 wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
1619 wxSocketFlags flags)
1620 : wxSocketBase(flags, wxSOCKET_SERVER)
1621 {
1622 wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
1623
1624 m_impl = wxSocketImpl::Create(*this);
1625
1626 if (!m_impl)
1627 {
1628 wxLogTrace( wxTRACE_Socket, _T("*** Failed to create m_impl") );
1629 return;
1630 }
1631
1632 // Setup the socket as server
1633 m_impl->SetLocal(addr_man.GetAddress());
1634
1635 if (GetFlags() & wxSOCKET_REUSEADDR) {
1636 m_impl->SetReusable();
1637 }
1638 if (GetFlags() & wxSOCKET_BROADCAST) {
1639 m_impl->SetBroadcast();
1640 }
1641 if (GetFlags() & wxSOCKET_NOBIND) {
1642 m_impl->DontDoBind();
1643 }
1644
1645 if (m_impl->CreateServer() != wxSOCKET_NOERROR)
1646 {
1647 delete m_impl;
1648 m_impl = NULL;
1649
1650 wxLogTrace( wxTRACE_Socket, _T("*** CreateServer() failed") );
1651 return;
1652 }
1653
1654 wxLogTrace( wxTRACE_Socket, _T("wxSocketServer on fd %d"), m_impl->m_fd );
1655 }
1656
1657 // --------------------------------------------------------------------------
1658 // Accept
1659 // --------------------------------------------------------------------------
1660
1661 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1662 {
1663 if (!m_impl)
1664 return false;
1665
1666 // If wait == false, then the call should be nonblocking.
1667 // When we are finished, we put the socket to blocking mode
1668 // again.
1669 wxSocketUnblocker unblock(m_impl, !wait);
1670 sock.m_impl = m_impl->WaitConnection(sock);
1671
1672 if ( !sock.m_impl )
1673 return false;
1674
1675 sock.m_type = wxSOCKET_BASE;
1676 sock.m_connected = true;
1677
1678 return true;
1679 }
1680
1681 wxSocketBase *wxSocketServer::Accept(bool wait)
1682 {
1683 wxSocketBase* sock = new wxSocketBase();
1684
1685 sock->SetFlags(m_flags);
1686
1687 if (!AcceptWith(*sock, wait))
1688 {
1689 sock->Destroy();
1690 sock = NULL;
1691 }
1692
1693 return sock;
1694 }
1695
1696 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1697 {
1698 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG);
1699 }
1700
1701 bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1702 {
1703 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1704
1705 SOCKOPTLEN_T lenreal;
1706 if ( getsockopt(m_impl->m_fd, level, optname,
1707 static_cast<char *>(optval), &lenreal) != 0 )
1708 return false;
1709
1710 *optlen = lenreal;
1711
1712 return true;
1713 }
1714
1715 bool
1716 wxSocketBase::SetOption(int level, int optname, const void *optval, int optlen)
1717 {
1718 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1719
1720 return setsockopt(m_impl->m_fd, level, optname,
1721 static_cast<const char *>(optval), optlen) == 0;
1722 }
1723
1724 bool wxSocketBase::SetLocal(const wxIPV4address& local)
1725 {
1726 GAddress* la = local.GetAddress();
1727
1728 // If the address is valid, save it for use when we call Connect
1729 if (la && la->m_addr)
1730 {
1731 m_localAddress = local;
1732
1733 return true;
1734 }
1735
1736 return false;
1737 }
1738
1739 // ==========================================================================
1740 // wxSocketClient
1741 // ==========================================================================
1742
1743 // --------------------------------------------------------------------------
1744 // Ctor and dtor
1745 // --------------------------------------------------------------------------
1746
1747 wxSocketClient::wxSocketClient(wxSocketFlags flags)
1748 : wxSocketBase(flags, wxSOCKET_CLIENT)
1749 {
1750 m_initialRecvBufferSize =
1751 m_initialSendBufferSize = -1;
1752 }
1753
1754 wxSocketClient::~wxSocketClient()
1755 {
1756 }
1757
1758 // --------------------------------------------------------------------------
1759 // Connect
1760 // --------------------------------------------------------------------------
1761
1762 bool wxSocketClient::DoConnect(const wxSockAddress& addr_man,
1763 const wxSockAddress* local,
1764 bool wait)
1765 {
1766 if (m_impl)
1767 {
1768 // Shutdown and destroy the socket
1769 Close();
1770 delete m_impl;
1771 }
1772
1773 m_impl = wxSocketImpl::Create(*this);
1774 m_connected = false;
1775 m_establishing = false;
1776
1777 if (!m_impl)
1778 return false;
1779
1780 // If wait == false, then the call should be nonblocking. When we are
1781 // finished, we put the socket to blocking mode again.
1782 wxSocketUnblocker unblock(m_impl, !wait);
1783
1784 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1785 if (GetFlags() & wxSOCKET_REUSEADDR)
1786 {
1787 m_impl->SetReusable();
1788 }
1789 if (GetFlags() & wxSOCKET_BROADCAST)
1790 {
1791 m_impl->SetBroadcast();
1792 }
1793 if (GetFlags() & wxSOCKET_NOBIND)
1794 {
1795 m_impl->DontDoBind();
1796 }
1797
1798 // If no local address was passed and one has been set, use the one that was Set
1799 if (!local && m_localAddress.GetAddress())
1800 {
1801 local = &m_localAddress;
1802 }
1803
1804 // Bind to the local IP address and port, when provided
1805 if (local)
1806 {
1807 GAddress* la = local->GetAddress();
1808
1809 if (la && la->m_addr)
1810 m_impl->SetLocal(la);
1811 }
1812
1813 m_impl->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
1814
1815 m_impl->SetPeer(addr_man.GetAddress());
1816 const wxSocketError err = m_impl->CreateClient();
1817
1818 if (err != wxSOCKET_NOERROR)
1819 {
1820 if (err == wxSOCKET_WOULDBLOCK)
1821 m_establishing = true;
1822
1823 return false;
1824 }
1825
1826 m_connected = true;
1827 return true;
1828 }
1829
1830 bool wxSocketClient::Connect(const wxSockAddress& addr_man, bool wait)
1831 {
1832 return DoConnect(addr_man, NULL, wait);
1833 }
1834
1835 bool wxSocketClient::Connect(const wxSockAddress& addr_man,
1836 const wxSockAddress& local,
1837 bool wait)
1838 {
1839 return DoConnect(addr_man, &local, wait);
1840 }
1841
1842 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1843 {
1844 if ( m_connected )
1845 {
1846 // this happens if the initial attempt to connect succeeded without
1847 // blocking
1848 return true;
1849 }
1850
1851 wxCHECK_MSG( m_establishing && m_impl, false,
1852 "No connection establishment attempt in progress" );
1853
1854 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1855 // true if the connection establishment process is finished, whether it is
1856 // over because we successfully connected or because we were not able to
1857 // connect
1858 return DoWait(seconds, milliseconds,
1859 wxSOCKET_CONNECTION_FLAG | wxSOCKET_LOST_FLAG);
1860 }
1861
1862 // ==========================================================================
1863 // wxDatagramSocket
1864 // ==========================================================================
1865
1866 wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
1867 wxSocketFlags flags )
1868 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
1869 {
1870 // Create the socket
1871 m_impl = wxSocketImpl::Create(*this);
1872
1873 if (!m_impl)
1874 return;
1875
1876 // Setup the socket as non connection oriented
1877 m_impl->SetLocal(addr.GetAddress());
1878 if (flags & wxSOCKET_REUSEADDR)
1879 {
1880 m_impl->SetReusable();
1881 }
1882 if (GetFlags() & wxSOCKET_BROADCAST)
1883 {
1884 m_impl->SetBroadcast();
1885 }
1886 if (GetFlags() & wxSOCKET_NOBIND)
1887 {
1888 m_impl->DontDoBind();
1889 }
1890
1891 if ( m_impl->CreateUDP() != wxSOCKET_NOERROR )
1892 {
1893 delete m_impl;
1894 m_impl = NULL;
1895 return;
1896 }
1897
1898 // Initialize all stuff
1899 m_connected = false;
1900 m_establishing = false;
1901 }
1902
1903 wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
1904 void* buf,
1905 wxUint32 nBytes )
1906 {
1907 Read(buf, nBytes);
1908 GetPeer(addr);
1909 return (*this);
1910 }
1911
1912 wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
1913 const void* buf,
1914 wxUint32 nBytes )
1915 {
1916 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1917
1918 m_impl->SetPeer(addr.GetAddress());
1919 Write(buf, nBytes);
1920 return (*this);
1921 }
1922
1923 // ==========================================================================
1924 // wxSocketModule
1925 // ==========================================================================
1926
1927 class wxSocketModule : public wxModule
1928 {
1929 public:
1930 virtual bool OnInit()
1931 {
1932 // wxSocketBase will call Initialize() itself only if sockets are
1933 // really used, don't do it from here
1934 return true;
1935 }
1936
1937 virtual void OnExit()
1938 {
1939 if ( wxSocketBase::IsInitialized() )
1940 wxSocketBase::Shutdown();
1941 }
1942
1943 private:
1944 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1945 };
1946
1947 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1948
1949 #endif // wxUSE_SOCKETS