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