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