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