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