]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
more fixes for using wxSocket in console applications (patch 1756260)
[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
41 #include "wx/sckaddr.h"
42 #include "wx/stopwatch.h"
43
44 // DLL options compatibility check:
45 #include "wx/build.h"
46 WX_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
80 IMPLEMENT_CLASS(wxSocketBase, wxObject)
81 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
82 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
83 IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
84 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
85
86 // --------------------------------------------------------------------------
87 // private classes
88 // --------------------------------------------------------------------------
89
90 class wxSocketState : public wxObject
91 {
92 public:
93 wxSocketFlags m_flags;
94 wxSocketEventFlags m_eventmask;
95 bool m_notify;
96 void *m_clientData;
97
98 public:
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
114 size_t wxSocketBase::m_countInit = 0;
115
116 bool wxSocketBase::IsInitialized()
117 {
118 return m_countInit > 0;
119 }
120
121 bool 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
161 void 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
175 void 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
211 wxSocketBase::wxSocketBase()
212 {
213 Init();
214 }
215
216 wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
217 {
218 Init();
219
220 m_flags = flags;
221 m_type = type;
222 }
223
224 wxSocketBase::~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
245 bool 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
283 bool 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
303 wxSocketBase& 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
322 wxUint32 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
383 wxSocketBase& 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
473 exit:
474 m_error = error;
475 m_lcount = total;
476 m_reading = false;
477 SetFlags(old_flags);
478
479 return *this;
480 }
481
482 wxSocketBase& 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
502 wxSocketBase& 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
521 wxUint32 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
574 wxSocketBase& 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
621 exit:
622 m_error = error;
623 m_lcount = total;
624 m_writing = false;
625
626 return *this;
627 }
628
629 wxSocketBase& 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
640 wxSocketBase& 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
678 bool 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
779 bool 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
787 bool 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
803 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
804 {
805 return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
806 }
807
808 bool 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
821 bool 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
841 bool 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
859 void 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
873 void 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
897 void wxSocketBase::SetTimeout(long seconds)
898 {
899 m_timeout = seconds;
900
901 if (m_socket)
902 m_socket->SetTimeout(m_timeout * 1000);
903 }
904
905 void 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
933 extern "C"
934 void 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
943 void 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
1009 void wxSocketBase::Notify(bool notify)
1010 {
1011 m_notify = notify;
1012 if ( m_socket )
1013 m_socket->Notify(notify);
1014 }
1015
1016 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1017 {
1018 m_eventmask = flags;
1019 }
1020
1021 void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1022 {
1023 m_handler = &handler;
1024 m_id = id;
1025 }
1026
1027 // --------------------------------------------------------------------------
1028 // Pushback buffer
1029 // --------------------------------------------------------------------------
1030
1031 void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1032 {
1033 if (!size) return;
1034
1035 if (m_unread == NULL)
1036 m_unread = malloc(size);
1037 else
1038 {
1039 void *tmp;
1040
1041 tmp = malloc(m_unrd_size + size);
1042 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1043 free(m_unread);
1044
1045 m_unread = tmp;
1046 }
1047
1048 m_unrd_size += size;
1049
1050 memcpy(m_unread, buffer, size);
1051 }
1052
1053 wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1054 {
1055 if (!m_unrd_size)
1056 return 0;
1057
1058 if (size > (m_unrd_size-m_unrd_cur))
1059 size = m_unrd_size-m_unrd_cur;
1060
1061 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1062
1063 if (!peek)
1064 {
1065 m_unrd_cur += size;
1066 if (m_unrd_size == m_unrd_cur)
1067 {
1068 free(m_unread);
1069 m_unread = NULL;
1070 m_unrd_size = 0;
1071 m_unrd_cur = 0;
1072 }
1073 }
1074
1075 return size;
1076 }
1077
1078
1079 // ==========================================================================
1080 // wxSocketServer
1081 // ==========================================================================
1082
1083 // --------------------------------------------------------------------------
1084 // Ctor
1085 // --------------------------------------------------------------------------
1086
1087 wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
1088 wxSocketFlags flags)
1089 : wxSocketBase(flags, wxSOCKET_SERVER)
1090 {
1091 wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
1092
1093 m_socket = GSocket_new();
1094
1095 if (!m_socket)
1096 {
1097 wxLogTrace( wxTRACE_Socket, _T("*** GSocket_new failed") );
1098 return;
1099 }
1100
1101 // Setup the socket as server
1102 m_socket->Notify(m_notify);
1103 m_socket->SetLocal(addr_man.GetAddress());
1104
1105 if (GetFlags() & wxSOCKET_REUSEADDR) {
1106 m_socket->SetReusable();
1107 }
1108 if (GetFlags() & wxSOCKET_BROADCAST) {
1109 m_socket->SetBroadcast();
1110 }
1111 if (GetFlags() & wxSOCKET_NOBIND) {
1112 m_socket->DontDoBind();
1113 }
1114
1115 if (m_socket->SetServer() != GSOCK_NOERROR)
1116 {
1117 delete m_socket;
1118 m_socket = NULL;
1119
1120 wxLogTrace( wxTRACE_Socket, _T("*** GSocket_SetServer failed") );
1121 return;
1122 }
1123
1124 m_socket->SetTimeout(m_timeout * 1000);
1125 m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1126 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1127 wx_socket_callback, (char *)this);
1128
1129 wxLogTrace( wxTRACE_Socket, _T("wxSocketServer on fd %d"), m_socket->m_fd );
1130 }
1131
1132 // --------------------------------------------------------------------------
1133 // Accept
1134 // --------------------------------------------------------------------------
1135
1136 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1137 {
1138 GSocket *child_socket;
1139
1140 if (!m_socket)
1141 return false;
1142
1143 // If wait == false, then the call should be nonblocking.
1144 // When we are finished, we put the socket to blocking mode
1145 // again.
1146
1147 if (!wait)
1148 m_socket->SetNonBlocking(1);
1149
1150 child_socket = m_socket->WaitConnection();
1151
1152 if (!wait)
1153 m_socket->SetNonBlocking(0);
1154
1155 if (!child_socket)
1156 return false;
1157
1158 sock.m_type = wxSOCKET_BASE;
1159 sock.m_socket = child_socket;
1160 sock.m_connected = true;
1161
1162 sock.m_socket->SetTimeout(sock.m_timeout * 1000);
1163 sock.m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1164 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1165 wx_socket_callback, (char *)&sock);
1166
1167 return true;
1168 }
1169
1170 wxSocketBase *wxSocketServer::Accept(bool wait)
1171 {
1172 wxSocketBase* sock = new wxSocketBase();
1173
1174 sock->SetFlags(m_flags);
1175
1176 if (!AcceptWith(*sock, wait))
1177 {
1178 sock->Destroy();
1179 sock = NULL;
1180 }
1181
1182 return sock;
1183 }
1184
1185 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1186 {
1187 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1188 }
1189
1190 bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1191 {
1192 wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1193
1194 if (m_socket->GetSockOpt(level, optname, optval, optlen)
1195 != GSOCK_NOERROR)
1196 {
1197 return false;
1198 }
1199 return true;
1200 }
1201
1202 bool wxSocketBase::SetOption(int level, int optname, const void *optval,
1203 int optlen)
1204 {
1205 wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1206
1207 if (m_socket->SetSockOpt(level, optname, optval, optlen)
1208 != GSOCK_NOERROR)
1209 {
1210 return false;
1211 }
1212 return true;
1213 }
1214
1215 bool wxSocketBase::SetLocal(wxIPV4address& local)
1216 {
1217 GAddress* la = local.GetAddress();
1218
1219 // If the address is valid, save it for use when we call Connect
1220 if (la && la->m_addr)
1221 {
1222 m_localAddress = local;
1223
1224 return true;
1225 }
1226
1227 return false;
1228 }
1229
1230 // ==========================================================================
1231 // wxSocketClient
1232 // ==========================================================================
1233
1234 // --------------------------------------------------------------------------
1235 // Ctor and dtor
1236 // --------------------------------------------------------------------------
1237
1238 wxSocketClient::wxSocketClient(wxSocketFlags flags)
1239 : wxSocketBase(flags, wxSOCKET_CLIENT)
1240 {
1241 }
1242
1243 wxSocketClient::~wxSocketClient()
1244 {
1245 }
1246
1247 // --------------------------------------------------------------------------
1248 // Connect
1249 // --------------------------------------------------------------------------
1250
1251 bool wxSocketClient::DoConnect(wxSockAddress& addr_man, wxSockAddress* local, bool wait)
1252 {
1253 GSocketError err;
1254
1255 if (m_socket)
1256 {
1257 // Shutdown and destroy the socket
1258 Close();
1259 delete m_socket;
1260 }
1261
1262 m_socket = GSocket_new();
1263 m_connected = false;
1264 m_establishing = false;
1265
1266 if (!m_socket)
1267 return false;
1268
1269 m_socket->SetTimeout(m_timeout * 1000);
1270 m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1271 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1272 wx_socket_callback, (char *)this);
1273
1274 // If wait == false, then the call should be nonblocking.
1275 // When we are finished, we put the socket to blocking mode
1276 // again.
1277
1278 if (!wait)
1279 m_socket->SetNonBlocking(1);
1280
1281 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1282 if (GetFlags() & wxSOCKET_REUSEADDR)
1283 {
1284 m_socket->SetReusable();
1285 }
1286 if (GetFlags() & wxSOCKET_BROADCAST)
1287 {
1288 m_socket->SetBroadcast();
1289 }
1290 if (GetFlags() & wxSOCKET_NOBIND)
1291 {
1292 m_socket->DontDoBind();
1293 }
1294
1295 // If no local address was passed and one has been set, use the one that was Set
1296 if (!local && m_localAddress.GetAddress())
1297 {
1298 local = &m_localAddress;
1299 }
1300
1301 // Bind to the local IP address and port, when provided
1302 if (local)
1303 {
1304 GAddress* la = local->GetAddress();
1305
1306 if (la && la->m_addr)
1307 m_socket->SetLocal(la);
1308 }
1309
1310 m_socket->SetPeer(addr_man.GetAddress());
1311 err = m_socket->Connect(GSOCK_STREAMED);
1312
1313 // register for callbacks (call it after m_socket->m_fd was initialized)
1314 m_socket->Notify(m_notify);
1315
1316 if (!wait)
1317 m_socket->SetNonBlocking(0);
1318
1319 if (err != GSOCK_NOERROR)
1320 {
1321 if (err == GSOCK_WOULDBLOCK)
1322 m_establishing = true;
1323
1324 return false;
1325 }
1326
1327 m_connected = true;
1328 return true;
1329 }
1330
1331 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
1332 {
1333 return (DoConnect(addr_man, NULL, wait));
1334 }
1335
1336 bool wxSocketClient::Connect(wxSockAddress& addr_man, wxSockAddress& local, bool wait)
1337 {
1338 return (DoConnect(addr_man, &local, wait));
1339 }
1340
1341 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1342 {
1343 if (m_connected) // Already connected
1344 return true;
1345
1346 if (!m_establishing || !m_socket) // No connection in progress
1347 return false;
1348
1349 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG |
1350 GSOCK_LOST_FLAG);
1351 }
1352
1353 // ==========================================================================
1354 // wxDatagramSocket
1355 // ==========================================================================
1356
1357 /* NOTE: experimental stuff - might change */
1358
1359 wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
1360 wxSocketFlags flags )
1361 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
1362 {
1363 // Create the socket
1364 m_socket = GSocket_new();
1365
1366 if (!m_socket)
1367 {
1368 wxFAIL_MSG( _T("datagram socket not new'd") );
1369 return;
1370 }
1371 m_socket->Notify(m_notify);
1372 // Setup the socket as non connection oriented
1373 m_socket->SetLocal(addr.GetAddress());
1374 if (flags & wxSOCKET_REUSEADDR)
1375 {
1376 m_socket->SetReusable();
1377 }
1378 if (GetFlags() & wxSOCKET_BROADCAST)
1379 {
1380 m_socket->SetBroadcast();
1381 }
1382 if (GetFlags() & wxSOCKET_NOBIND)
1383 {
1384 m_socket->DontDoBind();
1385 }
1386 if ( m_socket->SetNonOriented() != GSOCK_NOERROR )
1387 {
1388 delete m_socket;
1389 m_socket = NULL;
1390 return;
1391 }
1392
1393 // Initialize all stuff
1394 m_connected = false;
1395 m_establishing = false;
1396 m_socket->SetTimeout( m_timeout );
1397 m_socket->SetCallback( GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1398 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1399 wx_socket_callback, (char*)this );
1400 }
1401
1402 wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
1403 void* buf,
1404 wxUint32 nBytes )
1405 {
1406 Read(buf, nBytes);
1407 GetPeer(addr);
1408 return (*this);
1409 }
1410
1411 wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
1412 const void* buf,
1413 wxUint32 nBytes )
1414 {
1415 wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1416
1417 m_socket->SetPeer(addr.GetAddress());
1418 Write(buf, nBytes);
1419 return (*this);
1420 }
1421
1422 // ==========================================================================
1423 // wxSocketModule
1424 // ==========================================================================
1425
1426 class wxSocketModule : public wxModule
1427 {
1428 public:
1429 virtual bool OnInit()
1430 {
1431 // wxSocketBase will call GSocket_Init() itself when/if needed
1432 return true;
1433 }
1434
1435 virtual void OnExit()
1436 {
1437 if ( wxSocketBase::IsInitialized() )
1438 wxSocketBase::Shutdown();
1439 }
1440
1441 private:
1442 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1443 };
1444
1445 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1446
1447 #endif
1448 // wxUSE_SOCKETS