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