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