]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
add wxScrollHelper::ShowScrollbars() (implemented for GTK only right now, generic...
[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 // ==========================================================================
507 // wxSocketBase
508 // ==========================================================================
509
510 // --------------------------------------------------------------------------
511 // Initialization and shutdown
512 // --------------------------------------------------------------------------
513
514 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
515 // to m_countInit with a crit section
516 size_t wxSocketBase::m_countInit = 0;
517
518 bool wxSocketBase::IsInitialized()
519 {
520 return m_countInit > 0;
521 }
522
523 bool wxSocketBase::Initialize()
524 {
525 if ( !m_countInit++ )
526 {
527 wxSocketManager * const manager = wxSocketManager::Get();
528 if ( !manager || !manager->OnInit() )
529 {
530 m_countInit--;
531
532 return false;
533 }
534 }
535
536 return true;
537 }
538
539 void wxSocketBase::Shutdown()
540 {
541 // we should be initialized
542 wxASSERT_MSG( m_countInit > 0, _T("extra call to Shutdown()") );
543 if ( --m_countInit == 0 )
544 {
545 wxSocketManager * const manager = wxSocketManager::Get();
546 wxCHECK_RET( manager, "should have a socket manager" );
547
548 manager->OnExit();
549 }
550 }
551
552 // --------------------------------------------------------------------------
553 // Ctor and dtor
554 // --------------------------------------------------------------------------
555
556 void wxSocketBase::Init()
557 {
558 m_impl = NULL;
559 m_type = wxSOCKET_UNINIT;
560
561 // state
562 m_flags = 0;
563 m_connected =
564 m_establishing =
565 m_reading =
566 m_writing =
567 m_error =
568 m_closed = false;
569 m_lcount = 0;
570 m_timeout = 600;
571 m_beingDeleted = false;
572
573 // pushback buffer
574 m_unread = NULL;
575 m_unrd_size = 0;
576 m_unrd_cur = 0;
577
578 // events
579 m_id = wxID_ANY;
580 m_handler = NULL;
581 m_clientData = NULL;
582 m_notify = false;
583 m_eventmask = 0;
584
585 if ( !IsInitialized() )
586 {
587 // this Initialize() will be undone by wxSocketModule::OnExit(), all
588 // the other calls to it should be matched by a call to Shutdown()
589 Initialize();
590 }
591 }
592
593 wxSocketBase::wxSocketBase()
594 {
595 Init();
596 }
597
598 wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
599 {
600 Init();
601
602 SetFlags(flags);
603
604 m_type = type;
605 }
606
607 wxSocketBase::~wxSocketBase()
608 {
609 // Just in case the app called Destroy() *and* then deleted the socket
610 // immediately: don't leave dangling pointers.
611 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
612 if ( traits )
613 traits->RemoveFromPendingDelete(this);
614
615 // Shutdown and close the socket
616 if (!m_beingDeleted)
617 Close();
618
619 // Destroy the implementation object
620 delete m_impl;
621
622 // Free the pushback buffer
623 if (m_unread)
624 free(m_unread);
625 }
626
627 bool wxSocketBase::Destroy()
628 {
629 // Delayed destruction: the socket will be deleted during the next idle
630 // loop iteration. This ensures that all pending events have been
631 // processed.
632 m_beingDeleted = true;
633
634 // Shutdown and close the socket
635 Close();
636
637 // Supress events from now on
638 Notify(false);
639
640 // schedule this object for deletion
641 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
642 if ( traits )
643 {
644 // let the traits object decide what to do with us
645 traits->ScheduleForDestroy(this);
646 }
647 else // no app or no traits
648 {
649 // in wxBase we might have no app object at all, don't leak memory
650 delete this;
651 }
652
653 return true;
654 }
655
656 // ----------------------------------------------------------------------------
657 // simply accessors
658 // ----------------------------------------------------------------------------
659
660 wxSocketError wxSocketBase::LastError() const
661 {
662 return m_impl->GetError();
663 }
664
665 // --------------------------------------------------------------------------
666 // Basic IO calls
667 // --------------------------------------------------------------------------
668
669 // The following IO operations update m_error and m_lcount:
670 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
671 //
672 // TODO: Should Connect, Accept and AcceptWith update m_error?
673
674 bool wxSocketBase::Close()
675 {
676 // Interrupt pending waits
677 InterruptWait();
678
679 if (m_impl)
680 m_impl->Shutdown();
681
682 m_connected = false;
683 m_establishing = false;
684 return true;
685 }
686
687 wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
688 {
689 // Mask read events
690 m_reading = true;
691
692 m_lcount = DoRead(buffer, nbytes);
693
694 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
695 if (m_flags & wxSOCKET_WAITALL)
696 m_error = (m_lcount != nbytes);
697 else
698 m_error = (m_lcount == 0);
699
700 // Allow read events from now on
701 m_reading = false;
702
703 return *this;
704 }
705
706 wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
707 {
708 // We use pointer arithmetic here which doesn't work with void pointers.
709 char *buffer = static_cast<char *>(buffer_);
710
711 // Try the push back buffer first, even before checking whether the socket
712 // is valid to allow reading previously pushed back data from an already
713 // closed socket.
714 wxUint32 total = GetPushback(buffer, nbytes, false);
715 nbytes -= total;
716 buffer += total;
717
718 // If it's indeed closed or if read everything, there is nothing more to do.
719 if ( !m_impl || !nbytes )
720 return total;
721
722 wxCHECK_MSG( buffer, 0, "NULL buffer" );
723
724
725 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
726 // polling the socket and don't block at all.
727 if ( m_flags & wxSOCKET_NOWAIT )
728 {
729 wxSocketUnblocker unblock(m_impl);
730 int ret = m_impl->Read(buffer, nbytes);
731 if ( ret < 0 )
732 return 0;
733
734 total += ret;
735 }
736 else // blocking socket
737 {
738 for ( ;; )
739 {
740 // Wait until socket becomes ready for reading dispatching the GUI
741 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
742 // specified to disable this.
743 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
744 break;
745
746 const int ret = m_impl->Read(buffer, nbytes);
747 if ( ret == 0 )
748 {
749 // for connection-oriented (e.g. TCP) sockets we can only read
750 // 0 bytes if the other end has been closed, and for
751 // connectionless ones (UDP) this flag doesn't make sense
752 // anyhow so we can set it to true too without doing any harm
753 m_closed = true;
754 break;
755 }
756
757 if ( ret < 0 )
758 {
759 // this will be always interpreted as error by Read()
760 return 0;
761 }
762
763 total += ret;
764
765 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
766 // something and we don't need to wait for all nbytes bytes to be
767 // read.
768 if ( !(m_flags & wxSOCKET_WAITALL) )
769 break;
770
771 // Otherwise continue reading until we do read everything.
772 nbytes -= ret;
773 if ( !nbytes )
774 break;
775
776 buffer += ret;
777 }
778 }
779
780 return total;
781 }
782
783 wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
784 {
785 wxUint32 len, len2, sig, total;
786 bool error;
787 int old_flags;
788 struct
789 {
790 unsigned char sig[4];
791 unsigned char len[4];
792 } msg;
793
794 // Mask read events
795 m_reading = true;
796
797 total = 0;
798 error = true;
799 old_flags = m_flags;
800 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
801
802 if (DoRead(&msg, sizeof(msg)) != sizeof(msg))
803 goto exit;
804
805 sig = (wxUint32)msg.sig[0];
806 sig |= (wxUint32)(msg.sig[1] << 8);
807 sig |= (wxUint32)(msg.sig[2] << 16);
808 sig |= (wxUint32)(msg.sig[3] << 24);
809
810 if (sig != 0xfeeddead)
811 {
812 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
813 goto exit;
814 }
815
816 len = (wxUint32)msg.len[0];
817 len |= (wxUint32)(msg.len[1] << 8);
818 len |= (wxUint32)(msg.len[2] << 16);
819 len |= (wxUint32)(msg.len[3] << 24);
820
821 if (len > nbytes)
822 {
823 len2 = len - nbytes;
824 len = nbytes;
825 }
826 else
827 len2 = 0;
828
829 // Don't attempt to read if the msg was zero bytes long.
830 if (len)
831 {
832 total = DoRead(buffer, len);
833
834 if (total != len)
835 goto exit;
836 }
837
838 if (len2)
839 {
840 char *discard_buffer = new char[MAX_DISCARD_SIZE];
841 long discard_len;
842
843 // NOTE: discarded bytes don't add to m_lcount.
844 do
845 {
846 discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
847 discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
848 len2 -= (wxUint32)discard_len;
849 }
850 while ((discard_len > 0) && len2);
851
852 delete [] discard_buffer;
853
854 if (len2 != 0)
855 goto exit;
856 }
857 if (DoRead(&msg, sizeof(msg)) != sizeof(msg))
858 goto exit;
859
860 sig = (wxUint32)msg.sig[0];
861 sig |= (wxUint32)(msg.sig[1] << 8);
862 sig |= (wxUint32)(msg.sig[2] << 16);
863 sig |= (wxUint32)(msg.sig[3] << 24);
864
865 if (sig != 0xdeadfeed)
866 {
867 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
868 goto exit;
869 }
870
871 // everything was OK
872 error = false;
873
874 exit:
875 m_error = error;
876 m_lcount = total;
877 m_reading = false;
878 SetFlags(old_flags);
879
880 return *this;
881 }
882
883 wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
884 {
885 // Mask read events
886 m_reading = true;
887
888 m_lcount = DoRead(buffer, nbytes);
889 Pushback(buffer, m_lcount);
890
891 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
892 if (m_flags & wxSOCKET_WAITALL)
893 m_error = (m_lcount != nbytes);
894 else
895 m_error = (m_lcount == 0);
896
897 // Allow read events again
898 m_reading = false;
899
900 return *this;
901 }
902
903 wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
904 {
905 // Mask write events
906 m_writing = true;
907
908 m_lcount = DoWrite(buffer, nbytes);
909
910 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
911 if (m_flags & wxSOCKET_WAITALL)
912 m_error = (m_lcount != nbytes);
913 else
914 m_error = (m_lcount == 0);
915
916 // Allow write events again
917 m_writing = false;
918
919 return *this;
920 }
921
922 // This function is a mirror image of DoRead() except that it doesn't use the
923 // push back buffer, please see comments there
924 wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
925 {
926 const char *buffer = static_cast<const char *>(buffer_);
927
928 // Return if there is nothing to read or the socket is (already?) closed.
929 if ( !m_impl || !nbytes )
930 return 0;
931
932 wxCHECK_MSG( buffer, 0, "NULL buffer" );
933
934 wxUint32 total = 0;
935 if ( m_flags & wxSOCKET_NOWAIT )
936 {
937 wxSocketUnblocker unblock(m_impl);
938 const int ret = m_impl->Write(buffer, nbytes);
939 if ( ret > 0 )
940 total += ret;
941 }
942 else // blocking socket
943 {
944 for ( ;; )
945 {
946 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
947 break;
948
949 const int ret = m_impl->Write(buffer, nbytes);
950 if ( ret == 0 )
951 {
952 m_closed = true;
953 break;
954 }
955
956 if ( ret < 0 )
957 return 0;
958
959 total += ret;
960 if ( !(m_flags & wxSOCKET_WAITALL) )
961 break;
962
963 nbytes -= ret;
964 if ( !nbytes )
965 break;
966
967 buffer += ret;
968 }
969 }
970
971 return total;
972 }
973
974 wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
975 {
976 wxUint32 total;
977 bool error;
978 struct
979 {
980 unsigned char sig[4];
981 unsigned char len[4];
982 } msg;
983
984 // Mask write events
985 m_writing = true;
986
987 error = true;
988 total = 0;
989 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
990
991 msg.sig[0] = (unsigned char) 0xad;
992 msg.sig[1] = (unsigned char) 0xde;
993 msg.sig[2] = (unsigned char) 0xed;
994 msg.sig[3] = (unsigned char) 0xfe;
995
996 msg.len[0] = (unsigned char) (nbytes & 0xff);
997 msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
998 msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
999 msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
1000
1001 if (DoWrite(&msg, sizeof(msg)) < sizeof(msg))
1002 goto exit;
1003
1004 total = DoWrite(buffer, nbytes);
1005
1006 if (total < nbytes)
1007 goto exit;
1008
1009 msg.sig[0] = (unsigned char) 0xed;
1010 msg.sig[1] = (unsigned char) 0xfe;
1011 msg.sig[2] = (unsigned char) 0xad;
1012 msg.sig[3] = (unsigned char) 0xde;
1013 msg.len[0] =
1014 msg.len[1] =
1015 msg.len[2] =
1016 msg.len[3] = (char) 0;
1017
1018 if ((DoWrite(&msg, sizeof(msg))) < sizeof(msg))
1019 goto exit;
1020
1021 // everything was OK
1022 error = false;
1023
1024 exit:
1025 m_error = error;
1026 m_lcount = total;
1027 m_writing = false;
1028
1029 return *this;
1030 }
1031
1032 wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
1033 {
1034 if (nbytes != 0)
1035 Pushback(buffer, nbytes);
1036
1037 m_error = false;
1038 m_lcount = nbytes;
1039
1040 return *this;
1041 }
1042
1043 wxSocketBase& wxSocketBase::Discard()
1044 {
1045 char *buffer = new char[MAX_DISCARD_SIZE];
1046 wxUint32 ret;
1047 wxUint32 total = 0;
1048
1049 // Mask read events
1050 m_reading = true;
1051
1052 SetFlags(wxSOCKET_NOWAIT);
1053
1054 do
1055 {
1056 ret = DoRead(buffer, MAX_DISCARD_SIZE);
1057 total += ret;
1058 }
1059 while (ret == MAX_DISCARD_SIZE);
1060
1061 delete[] buffer;
1062 m_lcount = total;
1063 m_error = false;
1064
1065 // Allow read events again
1066 m_reading = false;
1067
1068 return *this;
1069 }
1070
1071 // --------------------------------------------------------------------------
1072 // Wait functions
1073 // --------------------------------------------------------------------------
1074
1075 /*
1076 * Polls the socket to determine its status. This function will
1077 * check for the events specified in the 'flags' parameter, and
1078 * it will return a mask indicating which operations can be
1079 * performed. This function won't block, regardless of the
1080 * mode (blocking | nonblocking) of the socket.
1081 */
1082 wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags)
1083 {
1084 assert(this);
1085
1086 wxSocketEventFlags result = 0;
1087 fd_set readfds;
1088 fd_set writefds;
1089 fd_set exceptfds;
1090 struct timeval tv;
1091
1092 if (m_fd == -1)
1093 return (wxSOCKET_LOST_FLAG & flags);
1094
1095 /* Do not use a static struct, Linux can garble it */
1096 tv.tv_sec = 0;
1097 tv.tv_usec = 0;
1098
1099 wxFD_ZERO(&readfds);
1100 wxFD_ZERO(&writefds);
1101 wxFD_ZERO(&exceptfds);
1102 wxFD_SET(m_fd, &readfds);
1103 if (flags & wxSOCKET_OUTPUT_FLAG || flags & wxSOCKET_CONNECTION_FLAG)
1104 wxFD_SET(m_fd, &writefds);
1105 wxFD_SET(m_fd, &exceptfds);
1106
1107 /* Check 'sticky' CONNECTION flag first */
1108 result |= wxSOCKET_CONNECTION_FLAG & m_detected;
1109
1110 /* If we have already detected a LOST event, then don't try
1111 * to do any further processing.
1112 */
1113 if ((m_detected & wxSOCKET_LOST_FLAG) != 0)
1114 {
1115 m_establishing = false;
1116 return (wxSOCKET_LOST_FLAG & flags);
1117 }
1118
1119 /* Try select now */
1120 if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0)
1121 {
1122 /* What to do here? */
1123 return (result & flags);
1124 }
1125
1126 /* Check for exceptions and errors */
1127 if (wxFD_ISSET(m_fd, &exceptfds))
1128 {
1129 m_establishing = false;
1130 m_detected = wxSOCKET_LOST_FLAG;
1131
1132 /* LOST event: Abort any further processing */
1133 return (wxSOCKET_LOST_FLAG & flags);
1134 }
1135
1136 /* Check for readability */
1137 if (wxFD_ISSET(m_fd, &readfds))
1138 {
1139 result |= wxSOCKET_INPUT_FLAG;
1140
1141 if (m_server && m_stream)
1142 {
1143 /* This is a TCP server socket that detected a connection.
1144 While the INPUT_FLAG is also set, it doesn't matter on
1145 this kind of sockets, as we can only Accept() from them. */
1146 m_detected |= wxSOCKET_CONNECTION_FLAG;
1147 }
1148 }
1149
1150 /* Check for writability */
1151 if (wxFD_ISSET(m_fd, &writefds))
1152 {
1153 if (m_establishing && !m_server)
1154 {
1155 int error;
1156 SOCKOPTLEN_T len = sizeof(error);
1157 m_establishing = false;
1158 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1159
1160 if (error)
1161 {
1162 m_detected = wxSOCKET_LOST_FLAG;
1163
1164 /* LOST event: Abort any further processing */
1165 return (wxSOCKET_LOST_FLAG & flags);
1166 }
1167 else
1168 {
1169 m_detected |= wxSOCKET_CONNECTION_FLAG;
1170 }
1171 }
1172 else
1173 {
1174 result |= wxSOCKET_OUTPUT_FLAG;
1175 }
1176 }
1177
1178 return (result | m_detected) & flags;
1179 }
1180
1181 // All Wait functions poll the socket using Select() to
1182 // check for the specified combination of conditions, until one
1183 // of these conditions become true, an error occurs, or the
1184 // timeout elapses. The polling loop runs the event loop so that
1185 // this won't block the GUI.
1186
1187 bool
1188 wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
1189 {
1190 wxCHECK_MSG( m_impl, false, "can't wait on invalid socket" );
1191
1192 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1193 m_interrupt = false;
1194
1195
1196 // Use either the provided timeout or the default timeout value associated
1197 // with this socket.
1198 //
1199 // TODO: allow waiting forever, see #9443
1200 const long timeout = seconds == -1 ? m_timeout * 1000
1201 : seconds * 1000 + milliseconds;
1202 const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
1203
1204 // Get the active event loop which we'll use for the message dispatching
1205 // when running in the main thread
1206 wxEventLoopBase *eventLoop;
1207 if ( wxIsMainThread() )
1208 {
1209 eventLoop = wxEventLoop::GetActive();
1210 }
1211 else // in worker thread
1212 {
1213 // We never dispatch messages from threads other than the main one.
1214 eventLoop = NULL;
1215 }
1216
1217 // Wait in an active polling loop: notice that the loop is executed at
1218 // least once, even if timeout is 0 (i.e. polling).
1219 bool gotEvent = false;
1220 for ( ;; )
1221 {
1222 // We always stop waiting when the connection is lost as it doesn't
1223 // make sense to continue further, even if wxSOCKET_LOST_FLAG is not
1224 // specified in flags to wait for.
1225 const wxSocketEventFlags
1226 result = m_impl->Select(flags | wxSOCKET_LOST_FLAG);
1227
1228 // Incoming connection (server) or connection established (client)?
1229 if ( result & wxSOCKET_CONNECTION_FLAG )
1230 {
1231 m_connected = true;
1232 m_establishing = false;
1233 gotEvent = true;
1234 break;
1235 }
1236
1237 // Data available or output buffer ready?
1238 if ( (result & wxSOCKET_INPUT_FLAG) || (result & wxSOCKET_OUTPUT_FLAG) )
1239 {
1240 gotEvent = true;
1241 break;
1242 }
1243
1244 // Connection lost
1245 if ( result & wxSOCKET_LOST_FLAG )
1246 {
1247 m_connected = false;
1248 m_establishing = false;
1249 if ( flags & wxSOCKET_LOST_FLAG )
1250 gotEvent = true;
1251 break;
1252 }
1253
1254 if ( m_interrupt )
1255 break;
1256
1257 // Wait more?
1258 const wxMilliClock_t timeNow = wxGetLocalTimeMillis();
1259 if ( timeNow >= timeEnd )
1260 break;
1261
1262 if ( eventLoop )
1263 {
1264 // This function is only called if wxSOCKET_BLOCK flag was not used
1265 // and so we should dispatch the events if there is an event loop
1266 // capable of doing it.
1267 if ( eventLoop->Pending() )
1268 eventLoop->Dispatch();
1269 }
1270 #if wxUSE_THREADS
1271 else // no event loop or waiting in another thread
1272 {
1273 // We're busy waiting but at least give up the rest of our current
1274 // time slice.
1275 wxThread::Yield();
1276 }
1277 #endif // wxUSE_THREADS
1278 }
1279
1280 return gotEvent;
1281 }
1282
1283 bool wxSocketBase::Wait(long seconds, long milliseconds)
1284 {
1285 return DoWait(seconds, milliseconds,
1286 wxSOCKET_INPUT_FLAG |
1287 wxSOCKET_OUTPUT_FLAG |
1288 wxSOCKET_CONNECTION_FLAG |
1289 wxSOCKET_LOST_FLAG
1290 );
1291 }
1292
1293 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
1294 {
1295 // Check pushback buffer before entering DoWait
1296 if ( m_unread )
1297 return true;
1298
1299 // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
1300 // because of the semantics of WaitForRead: a return value of true means
1301 // that a Read call will return immediately, not that there is
1302 // actually data to read.
1303 return DoWait(seconds, milliseconds, wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
1304 }
1305
1306
1307 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
1308 {
1309 return DoWait(seconds, milliseconds, wxSOCKET_OUTPUT_FLAG | wxSOCKET_LOST_FLAG);
1310 }
1311
1312 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
1313 {
1314 return DoWait(seconds, milliseconds, wxSOCKET_LOST_FLAG);
1315 }
1316
1317 // --------------------------------------------------------------------------
1318 // Miscellaneous
1319 // --------------------------------------------------------------------------
1320
1321 //
1322 // Get local or peer address
1323 //
1324
1325 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
1326 {
1327 GAddress *peer;
1328
1329 if (!m_impl)
1330 return false;
1331
1332 peer = m_impl->GetPeer();
1333
1334 // copying a null address would just trigger an assert anyway
1335
1336 if (!peer)
1337 return false;
1338
1339 addr_man.SetAddress(peer);
1340 GAddress_destroy(peer);
1341
1342 return true;
1343 }
1344
1345 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
1346 {
1347 GAddress *local;
1348
1349 if (!m_impl)
1350 return false;
1351
1352 local = m_impl->GetLocal();
1353 addr_man.SetAddress(local);
1354 GAddress_destroy(local);
1355
1356 return true;
1357 }
1358
1359 //
1360 // Save and restore socket state
1361 //
1362
1363 void wxSocketBase::SaveState()
1364 {
1365 wxSocketState *state;
1366
1367 state = new wxSocketState();
1368
1369 state->m_flags = m_flags;
1370 state->m_notify = m_notify;
1371 state->m_eventmask = m_eventmask;
1372 state->m_clientData = m_clientData;
1373
1374 m_states.Append(state);
1375 }
1376
1377 void wxSocketBase::RestoreState()
1378 {
1379 wxList::compatibility_iterator node;
1380 wxSocketState *state;
1381
1382 node = m_states.GetLast();
1383 if (!node)
1384 return;
1385
1386 state = (wxSocketState *)node->GetData();
1387
1388 m_flags = state->m_flags;
1389 m_notify = state->m_notify;
1390 m_eventmask = state->m_eventmask;
1391 m_clientData = state->m_clientData;
1392
1393 m_states.Erase(node);
1394 delete state;
1395 }
1396
1397 //
1398 // Timeout and flags
1399 //
1400
1401 void wxSocketBase::SetTimeout(long seconds)
1402 {
1403 m_timeout = seconds;
1404
1405 if (m_impl)
1406 m_impl->SetTimeout(m_timeout * 1000);
1407 }
1408
1409 void wxSocketBase::SetFlags(wxSocketFlags flags)
1410 {
1411 // Do some sanity checking on the flags used: not all values can be used
1412 // together.
1413 wxASSERT_MSG( !(flags & wxSOCKET_NOWAIT) ||
1414 !(flags & (wxSOCKET_WAITALL | wxSOCKET_BLOCK)),
1415 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1416 "wxSOCKET_NOWAIT doesn't make sense" );
1417
1418 m_flags = flags;
1419 }
1420
1421
1422 // --------------------------------------------------------------------------
1423 // Event handling
1424 // --------------------------------------------------------------------------
1425
1426 void wxSocketBase::OnRequest(wxSocketNotify notification)
1427 {
1428 switch(notification)
1429 {
1430 case wxSOCKET_CONNECTION:
1431 m_establishing = false;
1432 m_connected = true;
1433 break;
1434
1435 // If we are in the middle of a R/W operation, do not
1436 // propagate events to users. Also, filter 'late' events
1437 // which are no longer valid.
1438
1439 case wxSOCKET_INPUT:
1440 if (m_reading || !m_impl->Select(wxSOCKET_INPUT_FLAG))
1441 return;
1442 break;
1443
1444 case wxSOCKET_OUTPUT:
1445 if (m_writing || !m_impl->Select(wxSOCKET_OUTPUT_FLAG))
1446 return;
1447 break;
1448
1449 case wxSOCKET_LOST:
1450 m_connected = false;
1451 m_establishing = false;
1452 break;
1453
1454 case wxSOCKET_MAX_EVENT:
1455 wxFAIL_MSG( "unexpected notification" );
1456 return;
1457 }
1458
1459 // Schedule the event
1460
1461 wxSocketEventFlags flag = 0;
1462 wxUnusedVar(flag);
1463 switch (notification)
1464 {
1465 case wxSOCKET_INPUT: flag = wxSOCKET_INPUT_FLAG; break;
1466 case wxSOCKET_OUTPUT: flag = wxSOCKET_OUTPUT_FLAG; break;
1467 case wxSOCKET_CONNECTION: flag = wxSOCKET_CONNECTION_FLAG; break;
1468 case wxSOCKET_LOST: flag = wxSOCKET_LOST_FLAG; break;
1469 default:
1470 wxLogWarning(_("wxSocket: unknown event!."));
1471 return;
1472 }
1473
1474 if (((m_eventmask & flag) == flag) && m_notify)
1475 {
1476 if (m_handler)
1477 {
1478 wxSocketEvent event(m_id);
1479 event.m_event = notification;
1480 event.m_clientData = m_clientData;
1481 event.SetEventObject(this);
1482
1483 m_handler->AddPendingEvent(event);
1484 }
1485 }
1486 }
1487
1488 void wxSocketBase::Notify(bool notify)
1489 {
1490 m_notify = notify;
1491 if (m_impl)
1492 m_impl->Notify(notify);
1493 }
1494
1495 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1496 {
1497 m_eventmask = flags;
1498 }
1499
1500 void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1501 {
1502 m_handler = &handler;
1503 m_id = id;
1504 }
1505
1506 // --------------------------------------------------------------------------
1507 // Pushback buffer
1508 // --------------------------------------------------------------------------
1509
1510 void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1511 {
1512 if (!size) return;
1513
1514 if (m_unread == NULL)
1515 m_unread = malloc(size);
1516 else
1517 {
1518 void *tmp;
1519
1520 tmp = malloc(m_unrd_size + size);
1521 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1522 free(m_unread);
1523
1524 m_unread = tmp;
1525 }
1526
1527 m_unrd_size += size;
1528
1529 memcpy(m_unread, buffer, size);
1530 }
1531
1532 wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1533 {
1534 wxCHECK_MSG( buffer, 0, "NULL buffer" );
1535
1536 if (!m_unrd_size)
1537 return 0;
1538
1539 if (size > (m_unrd_size-m_unrd_cur))
1540 size = m_unrd_size-m_unrd_cur;
1541
1542 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1543
1544 if (!peek)
1545 {
1546 m_unrd_cur += size;
1547 if (m_unrd_size == m_unrd_cur)
1548 {
1549 free(m_unread);
1550 m_unread = NULL;
1551 m_unrd_size = 0;
1552 m_unrd_cur = 0;
1553 }
1554 }
1555
1556 return size;
1557 }
1558
1559
1560 // ==========================================================================
1561 // wxSocketServer
1562 // ==========================================================================
1563
1564 // --------------------------------------------------------------------------
1565 // Ctor
1566 // --------------------------------------------------------------------------
1567
1568 wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
1569 wxSocketFlags flags)
1570 : wxSocketBase(flags, wxSOCKET_SERVER)
1571 {
1572 wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
1573
1574 m_impl = wxSocketImpl::Create(*this);
1575
1576 if (!m_impl)
1577 {
1578 wxLogTrace( wxTRACE_Socket, _T("*** Failed to create m_impl") );
1579 return;
1580 }
1581
1582 // Setup the socket as server
1583 m_impl->Notify(m_notify);
1584 m_impl->SetLocal(addr_man.GetAddress());
1585
1586 if (GetFlags() & wxSOCKET_REUSEADDR) {
1587 m_impl->SetReusable();
1588 }
1589 if (GetFlags() & wxSOCKET_BROADCAST) {
1590 m_impl->SetBroadcast();
1591 }
1592 if (GetFlags() & wxSOCKET_NOBIND) {
1593 m_impl->DontDoBind();
1594 }
1595
1596 if (m_impl->CreateServer() != wxSOCKET_NOERROR)
1597 {
1598 delete m_impl;
1599 m_impl = NULL;
1600
1601 wxLogTrace( wxTRACE_Socket, _T("*** CreateServer() failed") );
1602 return;
1603 }
1604
1605 wxLogTrace( wxTRACE_Socket, _T("wxSocketServer on fd %d"), m_impl->m_fd );
1606 }
1607
1608 // --------------------------------------------------------------------------
1609 // Accept
1610 // --------------------------------------------------------------------------
1611
1612 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1613 {
1614 if (!m_impl)
1615 return false;
1616
1617 // If wait == false, then the call should be nonblocking.
1618 // When we are finished, we put the socket to blocking mode
1619 // again.
1620 wxSocketUnblocker unblock(m_impl, !wait);
1621 sock.m_impl = m_impl->WaitConnection(sock);
1622
1623 if ( !sock.m_impl )
1624 return false;
1625
1626 sock.m_type = wxSOCKET_BASE;
1627 sock.m_connected = true;
1628
1629 return true;
1630 }
1631
1632 wxSocketBase *wxSocketServer::Accept(bool wait)
1633 {
1634 wxSocketBase* sock = new wxSocketBase();
1635
1636 sock->SetFlags(m_flags);
1637
1638 if (!AcceptWith(*sock, wait))
1639 {
1640 sock->Destroy();
1641 sock = NULL;
1642 }
1643
1644 return sock;
1645 }
1646
1647 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1648 {
1649 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG);
1650 }
1651
1652 bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1653 {
1654 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1655
1656 SOCKOPTLEN_T lenreal;
1657 if ( getsockopt(m_impl->m_fd, level, optname,
1658 static_cast<char *>(optval), &lenreal) != 0 )
1659 return false;
1660
1661 *optlen = lenreal;
1662
1663 return true;
1664 }
1665
1666 bool
1667 wxSocketBase::SetOption(int level, int optname, const void *optval, int optlen)
1668 {
1669 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1670
1671 return setsockopt(m_impl->m_fd, level, optname,
1672 static_cast<const char *>(optval), optlen) == 0;
1673 }
1674
1675 bool wxSocketBase::SetLocal(const wxIPV4address& local)
1676 {
1677 GAddress* la = local.GetAddress();
1678
1679 // If the address is valid, save it for use when we call Connect
1680 if (la && la->m_addr)
1681 {
1682 m_localAddress = local;
1683
1684 return true;
1685 }
1686
1687 return false;
1688 }
1689
1690 // ==========================================================================
1691 // wxSocketClient
1692 // ==========================================================================
1693
1694 // --------------------------------------------------------------------------
1695 // Ctor and dtor
1696 // --------------------------------------------------------------------------
1697
1698 wxSocketClient::wxSocketClient(wxSocketFlags flags)
1699 : wxSocketBase(flags, wxSOCKET_CLIENT)
1700 {
1701 m_initialRecvBufferSize =
1702 m_initialSendBufferSize = -1;
1703 }
1704
1705 wxSocketClient::~wxSocketClient()
1706 {
1707 }
1708
1709 // --------------------------------------------------------------------------
1710 // Connect
1711 // --------------------------------------------------------------------------
1712
1713 bool wxSocketClient::DoConnect(const wxSockAddress& addr_man,
1714 const wxSockAddress* local,
1715 bool wait)
1716 {
1717 if (m_impl)
1718 {
1719 // Shutdown and destroy the socket
1720 Close();
1721 delete m_impl;
1722 }
1723
1724 m_impl = wxSocketImpl::Create(*this);
1725 m_connected = false;
1726 m_establishing = false;
1727
1728 if (!m_impl)
1729 return false;
1730
1731 // If wait == false, then the call should be nonblocking. When we are
1732 // finished, we put the socket to blocking mode again.
1733 wxSocketUnblocker unblock(m_impl, !wait);
1734
1735 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1736 if (GetFlags() & wxSOCKET_REUSEADDR)
1737 {
1738 m_impl->SetReusable();
1739 }
1740 if (GetFlags() & wxSOCKET_BROADCAST)
1741 {
1742 m_impl->SetBroadcast();
1743 }
1744 if (GetFlags() & wxSOCKET_NOBIND)
1745 {
1746 m_impl->DontDoBind();
1747 }
1748
1749 // If no local address was passed and one has been set, use the one that was Set
1750 if (!local && m_localAddress.GetAddress())
1751 {
1752 local = &m_localAddress;
1753 }
1754
1755 // Bind to the local IP address and port, when provided
1756 if (local)
1757 {
1758 GAddress* la = local->GetAddress();
1759
1760 if (la && la->m_addr)
1761 m_impl->SetLocal(la);
1762 }
1763
1764 m_impl->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
1765
1766 m_impl->SetPeer(addr_man.GetAddress());
1767 const wxSocketError err = m_impl->CreateClient();
1768
1769 //this will register for callbacks - must be called after m_impl->m_fd was initialized
1770 m_impl->Notify(m_notify);
1771
1772 if (err != wxSOCKET_NOERROR)
1773 {
1774 if (err == wxSOCKET_WOULDBLOCK)
1775 m_establishing = true;
1776
1777 return false;
1778 }
1779
1780 m_connected = true;
1781 return true;
1782 }
1783
1784 bool wxSocketClient::Connect(const wxSockAddress& addr_man, bool wait)
1785 {
1786 return DoConnect(addr_man, NULL, wait);
1787 }
1788
1789 bool wxSocketClient::Connect(const wxSockAddress& addr_man,
1790 const wxSockAddress& local,
1791 bool wait)
1792 {
1793 return DoConnect(addr_man, &local, wait);
1794 }
1795
1796 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1797 {
1798 if ( m_connected )
1799 {
1800 // this happens if the initial attempt to connect succeeded without
1801 // blocking
1802 return true;
1803 }
1804
1805 wxCHECK_MSG( m_establishing && m_impl, false,
1806 "No connection establishment attempt in progress" );
1807
1808 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1809 // true if the connection establishment process is finished, whether it is
1810 // over because we successfully connected or because we were not able to
1811 // connect
1812 return DoWait(seconds, milliseconds,
1813 wxSOCKET_CONNECTION_FLAG | wxSOCKET_LOST_FLAG);
1814 }
1815
1816 // ==========================================================================
1817 // wxDatagramSocket
1818 // ==========================================================================
1819
1820 wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
1821 wxSocketFlags flags )
1822 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
1823 {
1824 // Create the socket
1825 m_impl = wxSocketImpl::Create(*this);
1826
1827 if (!m_impl)
1828 return;
1829
1830 m_impl->Notify(m_notify);
1831 // Setup the socket as non connection oriented
1832 m_impl->SetLocal(addr.GetAddress());
1833 if (flags & wxSOCKET_REUSEADDR)
1834 {
1835 m_impl->SetReusable();
1836 }
1837 if (GetFlags() & wxSOCKET_BROADCAST)
1838 {
1839 m_impl->SetBroadcast();
1840 }
1841 if (GetFlags() & wxSOCKET_NOBIND)
1842 {
1843 m_impl->DontDoBind();
1844 }
1845
1846 if ( m_impl->CreateUDP() != wxSOCKET_NOERROR )
1847 {
1848 delete m_impl;
1849 m_impl = NULL;
1850 return;
1851 }
1852
1853 // Initialize all stuff
1854 m_connected = false;
1855 m_establishing = false;
1856 }
1857
1858 wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
1859 void* buf,
1860 wxUint32 nBytes )
1861 {
1862 Read(buf, nBytes);
1863 GetPeer(addr);
1864 return (*this);
1865 }
1866
1867 wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
1868 const void* buf,
1869 wxUint32 nBytes )
1870 {
1871 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1872
1873 m_impl->SetPeer(addr.GetAddress());
1874 Write(buf, nBytes);
1875 return (*this);
1876 }
1877
1878 // ==========================================================================
1879 // wxSocketModule
1880 // ==========================================================================
1881
1882 class wxSocketModule : public wxModule
1883 {
1884 public:
1885 virtual bool OnInit()
1886 {
1887 // wxSocketBase will call Initialize() itself only if sockets are
1888 // really used, don't do it from here
1889 return true;
1890 }
1891
1892 virtual void OnExit()
1893 {
1894 if ( wxSocketBase::IsInitialized() )
1895 wxSocketBase::Shutdown();
1896 }
1897
1898 private:
1899 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1900 };
1901
1902 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1903
1904 #endif // wxUSE_SOCKETS