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