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