]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
fix warnings about hiding virtual wxGraphicsContext::DrawText() overloads by using...
[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 // All Wait functions poll the socket using GSocket_Select() to
724 // check for the specified combination of conditions, until one
725 // of these conditions become true, an error occurs, or the
726 // timeout elapses. The polling loop runs the event loop so that
727 // this won't block the GUI.
728
729 bool
730 wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
731 {
732 wxCHECK_MSG( m_socket, false, "can't wait on invalid socket" );
733
734 // This can be set to true from Interrupt() to exit this function a.s.a.p.
735 m_interrupt = false;
736
737
738 // Use either the provided timeout or the default timeout value associated
739 // with this socket.
740 //
741 // TODO: allow waiting forever, see #9443
742 const long timeout = seconds == -1 ? m_timeout * 1000
743 : seconds * 1000 + milliseconds;
744 const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
745
746 // Get the active event loop which we'll use for the message dispatching
747 // when running in the main thread
748 wxEventLoopBase *eventLoop;
749 if ( wxIsMainThread() )
750 {
751 eventLoop = wxEventLoop::GetActive();
752
753 #ifdef __WXMSW__
754 wxASSERT_MSG( eventLoop,
755 "Sockets won't work without a running event loop" );
756 #endif // __WXMSW__
757 }
758 else // in worker thread
759 {
760 // We never dispatch messages from threads other than the main one.
761 eventLoop = NULL;
762 }
763
764 // Wait in an active polling loop: notice that the loop is executed at
765 // least once, even if timeout is 0 (i.e. polling).
766 bool gotEvent = false;
767 for ( ;; )
768 {
769 // We always stop waiting when the connection is lost as it doesn't
770 // make sense to continue further, even if GSOCK_LOST_FLAG is not
771 // specified in flags to wait for.
772 const GSocketEventFlags
773 result = m_socket->Select(flags | GSOCK_LOST_FLAG);
774
775 // Incoming connection (server) or connection established (client)?
776 if ( result & GSOCK_CONNECTION_FLAG )
777 {
778 m_connected = true;
779 m_establishing = false;
780 gotEvent = true;
781 break;
782 }
783
784 // Data available or output buffer ready?
785 if ( (result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG) )
786 {
787 gotEvent = true;
788 break;
789 }
790
791 // Connection lost
792 if ( result & GSOCK_LOST_FLAG )
793 {
794 m_connected = false;
795 m_establishing = false;
796 if ( flags & GSOCK_LOST_FLAG )
797 gotEvent = true;
798 break;
799 }
800
801 if ( m_interrupt )
802 break;
803
804 // Wait more?
805 const wxMilliClock_t timeNow = wxGetLocalTimeMillis();
806 if ( timeNow >= timeEnd )
807 break;
808
809 if ( eventLoop )
810 {
811 // Dispatch the events when we run in the main thread and have an
812 // active event loop: without this sockets don't work at all under
813 // MSW as socket flags are only updated when socket messages are
814 // processed.
815 if ( eventLoop->Pending() )
816 eventLoop->Dispatch();
817 }
818 #if wxUSE_THREADS
819 else // no event loop or waiting in another thread
820 {
821 // We're busy waiting but at least give up the rest of our current
822 // time slice.
823 wxThread::Yield();
824 }
825 #endif // wxUSE_THREADS
826 }
827
828 return gotEvent;
829 }
830
831 bool wxSocketBase::Wait(long seconds, long milliseconds)
832 {
833 return DoWait(seconds, milliseconds,
834 GSOCK_INPUT_FLAG |
835 GSOCK_OUTPUT_FLAG |
836 GSOCK_CONNECTION_FLAG |
837 GSOCK_LOST_FLAG
838 );
839 }
840
841 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
842 {
843 // Check pushback buffer before entering DoWait
844 if ( m_unread )
845 return true;
846
847 // Note that GSOCK_INPUT_LOST has to be explicitly passed to DoWait
848 // because of the semantics of WaitForRead: a return value of true means
849 // that a GSocket_Read call will return immediately, not that there is
850 // actually data to read.
851 return DoWait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
852 }
853
854
855 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
856 {
857 return DoWait(seconds, milliseconds, GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
858 }
859
860 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
861 {
862 return DoWait(seconds, milliseconds, GSOCK_LOST_FLAG);
863 }
864
865 // --------------------------------------------------------------------------
866 // Miscellaneous
867 // --------------------------------------------------------------------------
868
869 //
870 // Get local or peer address
871 //
872
873 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
874 {
875 GAddress *peer;
876
877 if (!m_socket)
878 return false;
879
880 peer = m_socket->GetPeer();
881
882 // copying a null address would just trigger an assert anyway
883
884 if (!peer)
885 return false;
886
887 addr_man.SetAddress(peer);
888 GAddress_destroy(peer);
889
890 return true;
891 }
892
893 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
894 {
895 GAddress *local;
896
897 if (!m_socket)
898 return false;
899
900 local = m_socket->GetLocal();
901 addr_man.SetAddress(local);
902 GAddress_destroy(local);
903
904 return true;
905 }
906
907 //
908 // Save and restore socket state
909 //
910
911 void wxSocketBase::SaveState()
912 {
913 wxSocketState *state;
914
915 state = new wxSocketState();
916
917 state->m_flags = m_flags;
918 state->m_notify = m_notify;
919 state->m_eventmask = m_eventmask;
920 state->m_clientData = m_clientData;
921
922 m_states.Append(state);
923 }
924
925 void wxSocketBase::RestoreState()
926 {
927 wxList::compatibility_iterator node;
928 wxSocketState *state;
929
930 node = m_states.GetLast();
931 if (!node)
932 return;
933
934 state = (wxSocketState *)node->GetData();
935
936 m_flags = state->m_flags;
937 m_notify = state->m_notify;
938 m_eventmask = state->m_eventmask;
939 m_clientData = state->m_clientData;
940
941 m_states.Erase(node);
942 delete state;
943 }
944
945 //
946 // Timeout and flags
947 //
948
949 void wxSocketBase::SetTimeout(long seconds)
950 {
951 m_timeout = seconds;
952
953 if (m_socket)
954 m_socket->SetTimeout(m_timeout * 1000);
955 }
956
957 void wxSocketBase::SetFlags(wxSocketFlags flags)
958 {
959 // Do some sanity checking on the flags used: not all values can be used
960 // together.
961 wxASSERT_MSG( !(flags & wxSOCKET_NOWAIT) ||
962 !(flags & (wxSOCKET_WAITALL | wxSOCKET_BLOCK)),
963 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
964 "wxSOCKET_NOWAIT doesn't make sense" );
965
966 m_flags = flags;
967 }
968
969
970 // --------------------------------------------------------------------------
971 // Event handling
972 // --------------------------------------------------------------------------
973
974 // A note on how events are processed, which is probably the most
975 // difficult thing to get working right while keeping the same API
976 // and functionality for all platforms.
977 //
978 // When GSocket detects an event, it calls wx_socket_callback, which in
979 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
980 // object. OnRequest does some housekeeping, and if the event is to be
981 // propagated to the user, it creates a new wxSocketEvent object and
982 // posts it. The event is not processed immediately, but delayed with
983 // AddPendingEvent instead. This is necessary in order to decouple the
984 // event processing from wx_socket_callback; otherwise, subsequent IO
985 // calls made from the user event handler would fail, as gtk callbacks
986 // are not reentrant.
987 //
988 // Note that, unlike events, user callbacks (now deprecated) are _not_
989 // decoupled from wx_socket_callback and thus they suffer from a variety
990 // of problems. Avoid them where possible and use events instead.
991
992 extern "C"
993 void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket),
994 GSocketEvent notification,
995 char *cdata)
996 {
997 wxSocketBase *sckobj = (wxSocketBase *)cdata;
998
999 sckobj->OnRequest((wxSocketNotify) notification);
1000 }
1001
1002 void wxSocketBase::OnRequest(wxSocketNotify notification)
1003 {
1004 switch(notification)
1005 {
1006 case wxSOCKET_CONNECTION:
1007 m_establishing = false;
1008 m_connected = true;
1009 break;
1010
1011 // If we are in the middle of a R/W operation, do not
1012 // propagate events to users. Also, filter 'late' events
1013 // which are no longer valid.
1014
1015 case wxSOCKET_INPUT:
1016 if (m_reading || !m_socket->Select(GSOCK_INPUT_FLAG))
1017 return;
1018 break;
1019
1020 case wxSOCKET_OUTPUT:
1021 if (m_writing || !m_socket->Select(GSOCK_OUTPUT_FLAG))
1022 return;
1023 break;
1024
1025 case wxSOCKET_LOST:
1026 m_connected = false;
1027 m_establishing = false;
1028 break;
1029 }
1030
1031 // Schedule the event
1032
1033 wxSocketEventFlags flag = 0;
1034 wxUnusedVar(flag);
1035 switch (notification)
1036 {
1037 case GSOCK_INPUT: flag = GSOCK_INPUT_FLAG; break;
1038 case GSOCK_OUTPUT: flag = GSOCK_OUTPUT_FLAG; break;
1039 case GSOCK_CONNECTION: flag = GSOCK_CONNECTION_FLAG; break;
1040 case GSOCK_LOST: flag = GSOCK_LOST_FLAG; break;
1041 default:
1042 wxLogWarning(_("wxSocket: unknown event!."));
1043 return;
1044 }
1045
1046 if (((m_eventmask & flag) == flag) && m_notify)
1047 {
1048 if (m_handler)
1049 {
1050 wxSocketEvent event(m_id);
1051 event.m_event = notification;
1052 event.m_clientData = m_clientData;
1053 event.SetEventObject(this);
1054
1055 m_handler->AddPendingEvent(event);
1056 }
1057 }
1058 }
1059
1060 void wxSocketBase::Notify(bool notify)
1061 {
1062 m_notify = notify;
1063 if (m_socket)
1064 m_socket->Notify(notify);
1065 }
1066
1067 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1068 {
1069 m_eventmask = flags;
1070 }
1071
1072 void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1073 {
1074 m_handler = &handler;
1075 m_id = id;
1076 }
1077
1078 // --------------------------------------------------------------------------
1079 // Pushback buffer
1080 // --------------------------------------------------------------------------
1081
1082 void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1083 {
1084 if (!size) return;
1085
1086 if (m_unread == NULL)
1087 m_unread = malloc(size);
1088 else
1089 {
1090 void *tmp;
1091
1092 tmp = malloc(m_unrd_size + size);
1093 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1094 free(m_unread);
1095
1096 m_unread = tmp;
1097 }
1098
1099 m_unrd_size += size;
1100
1101 memcpy(m_unread, buffer, size);
1102 }
1103
1104 wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1105 {
1106 wxCHECK_MSG( buffer, 0, "NULL buffer" );
1107
1108 if (!m_unrd_size)
1109 return 0;
1110
1111 if (size > (m_unrd_size-m_unrd_cur))
1112 size = m_unrd_size-m_unrd_cur;
1113
1114 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1115
1116 if (!peek)
1117 {
1118 m_unrd_cur += size;
1119 if (m_unrd_size == m_unrd_cur)
1120 {
1121 free(m_unread);
1122 m_unread = NULL;
1123 m_unrd_size = 0;
1124 m_unrd_cur = 0;
1125 }
1126 }
1127
1128 return size;
1129 }
1130
1131
1132 // ==========================================================================
1133 // wxSocketServer
1134 // ==========================================================================
1135
1136 // --------------------------------------------------------------------------
1137 // Ctor
1138 // --------------------------------------------------------------------------
1139
1140 wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
1141 wxSocketFlags flags)
1142 : wxSocketBase(flags, wxSOCKET_SERVER)
1143 {
1144 wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
1145
1146 m_socket = GSocket_new();
1147
1148 if (!m_socket)
1149 {
1150 wxLogTrace( wxTRACE_Socket, _T("*** GSocket_new failed") );
1151 return;
1152 }
1153
1154 // Setup the socket as server
1155 m_socket->Notify(m_notify);
1156 m_socket->SetLocal(addr_man.GetAddress());
1157
1158 if (GetFlags() & wxSOCKET_REUSEADDR) {
1159 m_socket->SetReusable();
1160 }
1161 if (GetFlags() & wxSOCKET_BROADCAST) {
1162 m_socket->SetBroadcast();
1163 }
1164 if (GetFlags() & wxSOCKET_NOBIND) {
1165 m_socket->DontDoBind();
1166 }
1167
1168 if (m_socket->SetServer() != GSOCK_NOERROR)
1169 {
1170 delete m_socket;
1171 m_socket = NULL;
1172
1173 wxLogTrace( wxTRACE_Socket, _T("*** GSocket_SetServer failed") );
1174 return;
1175 }
1176
1177 m_socket->SetTimeout(m_timeout * 1000);
1178 m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1179 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1180 wx_socket_callback, (char *)this);
1181
1182 wxLogTrace( wxTRACE_Socket, _T("wxSocketServer on fd %d"), m_socket->m_fd );
1183 }
1184
1185 // --------------------------------------------------------------------------
1186 // Accept
1187 // --------------------------------------------------------------------------
1188
1189 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1190 {
1191 if (!m_socket)
1192 return false;
1193
1194 // If wait == false, then the call should be nonblocking.
1195 // When we are finished, we put the socket to blocking mode
1196 // again.
1197 wxSocketUnblocker unblock(m_socket, !wait);
1198 GSocket * const child_socket = m_socket->WaitConnection();
1199
1200 if (!child_socket)
1201 return false;
1202
1203 sock.m_type = wxSOCKET_BASE;
1204 sock.m_socket = child_socket;
1205 sock.m_connected = true;
1206
1207 sock.m_socket->SetTimeout(sock.m_timeout * 1000);
1208 sock.m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1209 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1210 wx_socket_callback, (char *)&sock);
1211
1212 return true;
1213 }
1214
1215 wxSocketBase *wxSocketServer::Accept(bool wait)
1216 {
1217 wxSocketBase* sock = new wxSocketBase();
1218
1219 sock->SetFlags(m_flags);
1220
1221 if (!AcceptWith(*sock, wait))
1222 {
1223 sock->Destroy();
1224 sock = NULL;
1225 }
1226
1227 return sock;
1228 }
1229
1230 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1231 {
1232 return DoWait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1233 }
1234
1235 bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1236 {
1237 wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1238
1239 if (m_socket->GetSockOpt(level, optname, optval, optlen)
1240 != GSOCK_NOERROR)
1241 {
1242 return false;
1243 }
1244 return true;
1245 }
1246
1247 bool wxSocketBase::SetOption(int level, int optname, const void *optval,
1248 int optlen)
1249 {
1250 wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1251
1252 if (m_socket->SetSockOpt(level, optname, optval, optlen)
1253 != GSOCK_NOERROR)
1254 {
1255 return false;
1256 }
1257 return true;
1258 }
1259
1260 bool wxSocketBase::SetLocal(const wxIPV4address& local)
1261 {
1262 GAddress* la = local.GetAddress();
1263
1264 // If the address is valid, save it for use when we call Connect
1265 if (la && la->m_addr)
1266 {
1267 m_localAddress = local;
1268
1269 return true;
1270 }
1271
1272 return false;
1273 }
1274
1275 // ==========================================================================
1276 // wxSocketClient
1277 // ==========================================================================
1278
1279 // --------------------------------------------------------------------------
1280 // Ctor and dtor
1281 // --------------------------------------------------------------------------
1282
1283 wxSocketClient::wxSocketClient(wxSocketFlags flags)
1284 : wxSocketBase(flags, wxSOCKET_CLIENT)
1285 {
1286 m_initialRecvBufferSize =
1287 m_initialSendBufferSize = -1;
1288 }
1289
1290 wxSocketClient::~wxSocketClient()
1291 {
1292 }
1293
1294 // --------------------------------------------------------------------------
1295 // Connect
1296 // --------------------------------------------------------------------------
1297
1298 bool wxSocketClient::DoConnect(const wxSockAddress& addr_man,
1299 const wxSockAddress* local,
1300 bool wait)
1301 {
1302 if (m_socket)
1303 {
1304 // Shutdown and destroy the socket
1305 Close();
1306 delete m_socket;
1307 }
1308
1309 m_socket = GSocket_new();
1310 m_connected = false;
1311 m_establishing = false;
1312
1313 if (!m_socket)
1314 return false;
1315
1316 m_socket->SetTimeout(m_timeout * 1000);
1317 m_socket->SetCallback(
1318 GSOCK_INPUT_FLAG |
1319 GSOCK_OUTPUT_FLAG |
1320 GSOCK_LOST_FLAG |
1321 GSOCK_CONNECTION_FLAG,
1322 wx_socket_callback,
1323 (char *)this
1324 );
1325
1326 // If wait == false, then the call should be nonblocking. When we are
1327 // finished, we put the socket to blocking mode again.
1328 wxSocketUnblocker unblock(m_socket, !wait);
1329
1330 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1331 if (GetFlags() & wxSOCKET_REUSEADDR)
1332 {
1333 m_socket->SetReusable();
1334 }
1335 if (GetFlags() & wxSOCKET_BROADCAST)
1336 {
1337 m_socket->SetBroadcast();
1338 }
1339 if (GetFlags() & wxSOCKET_NOBIND)
1340 {
1341 m_socket->DontDoBind();
1342 }
1343
1344 // If no local address was passed and one has been set, use the one that was Set
1345 if (!local && m_localAddress.GetAddress())
1346 {
1347 local = &m_localAddress;
1348 }
1349
1350 // Bind to the local IP address and port, when provided
1351 if (local)
1352 {
1353 GAddress* la = local->GetAddress();
1354
1355 if (la && la->m_addr)
1356 m_socket->SetLocal(la);
1357 }
1358
1359 #if defined(__WXMSW__) || defined(__WXGTK__)
1360 m_socket->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
1361 #endif
1362
1363 m_socket->SetPeer(addr_man.GetAddress());
1364 const GSocketError err = m_socket->Connect(GSOCK_STREAMED);
1365
1366 //this will register for callbacks - must be called after m_socket->m_fd was initialized
1367 m_socket->Notify(m_notify);
1368
1369 if (err != GSOCK_NOERROR)
1370 {
1371 if (err == GSOCK_WOULDBLOCK)
1372 m_establishing = true;
1373
1374 return false;
1375 }
1376
1377 m_connected = true;
1378 return true;
1379 }
1380
1381 bool wxSocketClient::Connect(const wxSockAddress& addr_man, bool wait)
1382 {
1383 return DoConnect(addr_man, NULL, wait);
1384 }
1385
1386 bool wxSocketClient::Connect(const wxSockAddress& addr_man,
1387 const wxSockAddress& local,
1388 bool wait)
1389 {
1390 return DoConnect(addr_man, &local, wait);
1391 }
1392
1393 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1394 {
1395 if ( m_connected )
1396 {
1397 // this happens if the initial attempt to connect succeeded without
1398 // blocking
1399 return true;
1400 }
1401
1402 wxCHECK_MSG( m_establishing && m_socket, false,
1403 "No connection establishment attempt in progress" );
1404
1405 // we must specify GSOCK_LOST_FLAG here explicitly because we must return
1406 // true if the connection establishment process is finished, whether it is
1407 // over because we successfully connected or because we were not able to
1408 // connect
1409 return DoWait(seconds, milliseconds,
1410 GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
1411 }
1412
1413 // ==========================================================================
1414 // wxDatagramSocket
1415 // ==========================================================================
1416
1417 /* NOTE: experimental stuff - might change */
1418
1419 wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
1420 wxSocketFlags flags )
1421 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
1422 {
1423 // Create the socket
1424 m_socket = GSocket_new();
1425
1426 if (!m_socket)
1427 {
1428 wxFAIL_MSG( _T("datagram socket not new'd") );
1429 return;
1430 }
1431 m_socket->Notify(m_notify);
1432 // Setup the socket as non connection oriented
1433 m_socket->SetLocal(addr.GetAddress());
1434 if (flags & wxSOCKET_REUSEADDR)
1435 {
1436 m_socket->SetReusable();
1437 }
1438 if (GetFlags() & wxSOCKET_BROADCAST)
1439 {
1440 m_socket->SetBroadcast();
1441 }
1442 if (GetFlags() & wxSOCKET_NOBIND)
1443 {
1444 m_socket->DontDoBind();
1445 }
1446 if ( m_socket->SetNonOriented() != GSOCK_NOERROR )
1447 {
1448 delete m_socket;
1449 m_socket = NULL;
1450 return;
1451 }
1452
1453 // Initialize all stuff
1454 m_connected = false;
1455 m_establishing = false;
1456 m_socket->SetTimeout( m_timeout );
1457 m_socket->SetCallback( GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1458 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1459 wx_socket_callback, (char*)this );
1460 }
1461
1462 wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
1463 void* buf,
1464 wxUint32 nBytes )
1465 {
1466 Read(buf, nBytes);
1467 GetPeer(addr);
1468 return (*this);
1469 }
1470
1471 wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
1472 const void* buf,
1473 wxUint32 nBytes )
1474 {
1475 wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1476
1477 m_socket->SetPeer(addr.GetAddress());
1478 Write(buf, nBytes);
1479 return (*this);
1480 }
1481
1482 // ==========================================================================
1483 // wxSocketModule
1484 // ==========================================================================
1485
1486 class wxSocketModule : public wxModule
1487 {
1488 public:
1489 virtual bool OnInit()
1490 {
1491 // wxSocketBase will call GSocket_Init() itself when/if needed
1492 return true;
1493 }
1494
1495 virtual void OnExit()
1496 {
1497 if ( wxSocketBase::IsInitialized() )
1498 wxSocketBase::Shutdown();
1499 }
1500
1501 private:
1502 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1503 };
1504
1505 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1506
1507 #endif // wxUSE_SOCKETS