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