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