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