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