]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
rename various gsock* files to sock* (except for MSW where this will be done later)
[wxWidgets.git] / src / common / socket.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/socket.cpp
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
5 // Created: April 1997
6 // Copyright: (C) 1999-1997, Guilhem Lavaux
7 // (C) 1999-2000, Guillermo Rodriguez Garcia
8 // (C) 2008 Vadim Zeitlin
9 // RCS_ID: $Id$
10 // License: wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12
13 // ==========================================================================
14 // Declarations
15 // ==========================================================================
16
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #if wxUSE_SOCKETS
25
26 #include "wx/socket.h"
27
28 #ifndef WX_PRECOMP
29 #include "wx/object.h"
30 #include "wx/string.h"
31 #include "wx/intl.h"
32 #include "wx/log.h"
33 #include "wx/event.h"
34 #include "wx/app.h"
35 #include "wx/utils.h"
36 #include "wx/timer.h"
37 #include "wx/module.h"
38 #endif
39
40 #include "wx/apptrait.h"
41 #include "wx/sckaddr.h"
42 #include "wx/stopwatch.h"
43 #include "wx/thread.h"
44 #include "wx/evtloop.h"
45
46 #include "wx/private/fd.h"
47 #include "wx/private/socket.h"
48
49 // DLL options compatibility check:
50 #include "wx/build.h"
51 WX_CHECK_BUILD_OPTIONS("wxNet")
52
53 // --------------------------------------------------------------------------
54 // macros and constants
55 // --------------------------------------------------------------------------
56
57 // discard buffer
58 #define MAX_DISCARD_SIZE (10 * 1024)
59
60 #define wxTRACE_Socket _T("wxSocket")
61
62 // --------------------------------------------------------------------------
63 // wxWin macros
64 // --------------------------------------------------------------------------
65
66 IMPLEMENT_CLASS(wxSocketBase, wxObject)
67 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
68 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
69 IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
70 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
71
72 // --------------------------------------------------------------------------
73 // private classes
74 // --------------------------------------------------------------------------
75
76 class wxSocketState : public wxObject
77 {
78 public:
79 wxSocketFlags m_flags;
80 wxSocketEventFlags m_eventmask;
81 bool m_notify;
82 void *m_clientData;
83
84 public:
85 wxSocketState() : wxObject() {}
86
87 DECLARE_NO_COPY_CLASS(wxSocketState)
88 };
89
90 // Conditionally make the socket non-blocking for the lifetime of this object.
91 class wxSocketUnblocker
92 {
93 public:
94 wxSocketUnblocker(wxSocketImpl *socket, bool unblock = true)
95 : m_impl(socket),
96 m_unblock(unblock)
97 {
98 if ( m_unblock )
99 m_impl->SetNonBlocking(true);
100 }
101
102 ~wxSocketUnblocker()
103 {
104 if ( m_unblock )
105 m_impl->SetNonBlocking(false);
106 }
107
108 private:
109 wxSocketImpl * const m_impl;
110 bool m_unblock;
111
112 DECLARE_NO_COPY_CLASS(wxSocketUnblocker)
113 };
114
115 // ============================================================================
116 // wxSocketManager
117 // ============================================================================
118
119 wxSocketManager *wxSocketManager::ms_manager = NULL;
120
121 /* static */
122 void wxSocketManager::Set(wxSocketManager *manager)
123 {
124 wxASSERT_MSG( !ms_manager, "too late to set manager now" );
125
126 ms_manager = manager;
127 }
128
129 /* static */
130 void wxSocketManager::Init()
131 {
132 wxASSERT_MSG( !ms_manager, "shouldn't be initialized twice" );
133
134 /*
135 Details: Initialize() creates a hidden window as a sink for socket
136 events, such as 'read completed'. wxMSW has only one message loop
137 for the main thread. If Initialize is called in a secondary thread,
138 the socket window will be created for the secondary thread, but
139 since there is no message loop on this thread, it will never
140 receive events and all socket operations will time out.
141 BTW, the main thread must not be stopped using sleep or block
142 on a semaphore (a bad idea in any case) or socket operations
143 will time out.
144
145 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
146 the main thread. Because secondary threads do not have run loops,
147 adding event notifications to the "Current" loop would have no
148 effect at all, events would never fire.
149 */
150 wxASSERT_MSG( wxIsMainThread(),
151 "sockets must be initialized from the main thread" );
152
153 wxAppConsole * const app = wxAppConsole::GetInstance();
154 wxCHECK_RET( app, "sockets can't be initialized without wxApp" );
155
156 ms_manager = app->GetTraits()->GetSocketManager();
157 }
158
159 // ==========================================================================
160 // wxSocketImpl
161 // ==========================================================================
162
163 /* static */
164 wxSocketImpl *wxSocketImpl::Create(wxSocketBase& wxsocket)
165 {
166 wxSocketManager * const manager = wxSocketManager::Get();
167 return manager ? manager->CreateSocket(wxsocket) : NULL;
168 }
169
170 wxSocketImpl::wxSocketImpl(wxSocketBase& wxsocket)
171 : m_wxsocket(&wxsocket)
172 {
173 m_fd = INVALID_SOCKET;
174 m_detected = 0;
175 m_local = NULL;
176 m_peer = NULL;
177 m_error = wxSOCKET_NOERROR;
178 m_server = false;
179 m_stream = true;
180 m_non_blocking = false;
181
182 SetTimeout(wxsocket.GetTimeout() * 1000);
183
184 m_establishing = false;
185 m_reusable = false;
186 m_broadcast = false;
187 m_dobind = true;
188 m_initialRecvBufferSize = -1;
189 m_initialSendBufferSize = -1;
190 }
191
192 wxSocketImpl::~wxSocketImpl()
193 {
194 if (m_fd != INVALID_SOCKET)
195 Shutdown();
196
197 if (m_local)
198 GAddress_destroy(m_local);
199
200 if (m_peer)
201 GAddress_destroy(m_peer);
202 }
203
204 bool wxSocketImpl::PreCreateCheck(GAddress *addr)
205 {
206 if ( m_fd != INVALID_SOCKET )
207 {
208 m_error = wxSOCKET_INVSOCK;
209 return false;
210 }
211
212 if ( !addr || !addr->m_addr )
213 {
214 m_error = wxSOCKET_INVADDR;
215 return false;
216 }
217
218 return true;
219 }
220
221 void wxSocketImpl::PostCreation()
222 {
223 // FreeBSD variants can't use MSG_NOSIGNAL, and instead use a socket option
224 #ifdef SO_NOSIGPIPE
225 EnableSocketOption(SO_NOSIGPIPE);
226 #endif
227
228 if ( m_reusable )
229 EnableSocketOption(SO_REUSEADDR);
230
231 if ( m_broadcast )
232 {
233 wxASSERT_MSG( !m_stream, "broadcasting is for datagram sockets only" );
234
235 EnableSocketOption(SO_BROADCAST);
236 }
237
238 if ( m_initialRecvBufferSize >= 0 )
239 SetSocketOption(SO_RCVBUF, m_initialRecvBufferSize);
240 if ( m_initialSendBufferSize >= 0 )
241 SetSocketOption(SO_SNDBUF, m_initialSendBufferSize);
242
243 // FIXME: shouldn't we check for m_non_blocking here? as it is now, all our
244 // sockets are non-blocking
245 UnblockAndRegisterWithEventLoop();
246 }
247
248 wxSocketError wxSocketImpl::UpdateLocalAddress()
249 {
250 WX_SOCKLEN_T lenAddr;
251 if ( getsockname(m_fd, m_local->m_addr, &lenAddr) != 0 )
252 {
253 Close();
254 m_error = wxSOCKET_IOERR;
255 return m_error;
256 }
257
258 m_local->m_len = lenAddr;
259
260 return wxSOCKET_NOERROR;
261 }
262
263 wxSocketError wxSocketImpl::CreateServer()
264 {
265 if ( !PreCreateCheck(m_local) )
266 return m_error;
267
268 m_server = true;
269 m_stream = true;
270
271 // do create the socket
272 m_fd = socket(m_local->m_realfamily, SOCK_STREAM, 0);
273
274 if ( m_fd == INVALID_SOCKET )
275 {
276 m_error = wxSOCKET_IOERR;
277 return wxSOCKET_IOERR;
278 }
279
280 PostCreation();
281
282 // and then bind to and listen on it
283 //
284 // FIXME: should we test for m_dobind here?
285 if ( bind(m_fd, m_local->m_addr, m_local->m_len) != 0 )
286 m_error = wxSOCKET_IOERR;
287
288 if ( IsOk() )
289 {
290 if ( listen(m_fd, 5) != 0 )
291 m_error = wxSOCKET_IOERR;
292 }
293
294 if ( !IsOk() )
295 {
296 Close();
297 return m_error;
298 }
299
300 // finally retrieve the address we effectively bound to
301 return UpdateLocalAddress();
302 }
303
304 wxSocketError wxSocketImpl::CreateClient()
305 {
306 if ( !PreCreateCheck(m_peer) )
307 return m_error;
308
309 m_fd = socket(m_peer->m_realfamily, SOCK_STREAM, 0);
310
311 if ( m_fd == INVALID_SOCKET )
312 {
313 m_error = wxSOCKET_IOERR;
314 return wxSOCKET_IOERR;
315 }
316
317 PostCreation();
318
319 // If a local address has been set, then bind to it before calling connect
320 if ( m_local && m_local->m_addr )
321 {
322 if ( bind(m_fd, m_local->m_addr, m_local->m_len) != 0 )
323 {
324 Close();
325 m_error = wxSOCKET_IOERR;
326 return m_error;
327 }
328 }
329
330 // Connect to the peer and handle the EWOULDBLOCK return value in
331 // platform-specific code
332 return DoHandleConnect(connect(m_fd, m_peer->m_addr, m_peer->m_len));
333 }
334
335
336 wxSocketError wxSocketImpl::CreateUDP()
337 {
338 if ( !PreCreateCheck(m_local) )
339 return m_error;
340
341 m_stream = false;
342 m_server = false;
343
344 m_fd = socket(m_local->m_realfamily, SOCK_DGRAM, 0);
345
346 if ( m_fd == INVALID_SOCKET )
347 {
348 m_error = wxSOCKET_IOERR;
349 return wxSOCKET_IOERR;
350 }
351
352 PostCreation();
353
354 if ( m_dobind )
355 {
356 if ( bind(m_fd, m_local->m_addr, m_local->m_len) != 0 )
357 {
358 Close();
359 m_error = wxSOCKET_IOERR;
360 return m_error;
361 }
362
363 return UpdateLocalAddress();
364 }
365
366 return wxSOCKET_NOERROR;
367 }
368
369
370 void wxSocketImpl::Close()
371 {
372 if ( m_fd != INVALID_SOCKET )
373 {
374 DoClose();
375 m_fd = INVALID_SOCKET;
376 }
377 }
378
379 /*
380 * Disallow further read/write operations on this socket, close
381 * the fd and disable all callbacks.
382 */
383 void wxSocketImpl::Shutdown()
384 {
385 if ( m_fd != INVALID_SOCKET )
386 {
387 shutdown(m_fd, 1 /* SD_SEND */);
388 Close();
389 }
390
391 m_detected = wxSOCKET_LOST_FLAG;
392 }
393
394 /*
395 * Sets the timeout for blocking calls. Time is expressed in
396 * milliseconds.
397 */
398 void wxSocketImpl::SetTimeout(unsigned long millis)
399 {
400 m_timeout.tv_sec = (millis / 1000);
401 m_timeout.tv_usec = (millis % 1000) * 1000;
402 }
403
404 void wxSocketImpl::NotifyOnStateChange(wxSocketNotify event)
405 {
406 m_wxsocket->OnRequest(event);
407 }
408
409 /* Address handling */
410
411 /*
412 * Set or get the local or peer address for this socket. The 'set'
413 * functions return wxSOCKET_NOERROR on success, an error code otherwise.
414 * The 'get' functions return a pointer to a GAddress object on success,
415 * or NULL otherwise, in which case they set the error code of the
416 * corresponding socket.
417 *
418 * Error codes:
419 * wxSOCKET_INVSOCK - the socket is not valid.
420 * wxSOCKET_INVADDR - the address is not valid.
421 */
422 wxSocketError wxSocketImpl::SetLocal(GAddress *address)
423 {
424 /* the socket must be initialized, or it must be a server */
425 if (m_fd != INVALID_SOCKET && !m_server)
426 {
427 m_error = wxSOCKET_INVSOCK;
428 return wxSOCKET_INVSOCK;
429 }
430
431 /* check address */
432 if (address == NULL || address->m_family == wxSOCKET_NOFAMILY)
433 {
434 m_error = wxSOCKET_INVADDR;
435 return wxSOCKET_INVADDR;
436 }
437
438 if (m_local)
439 GAddress_destroy(m_local);
440
441 m_local = GAddress_copy(address);
442
443 return wxSOCKET_NOERROR;
444 }
445
446 wxSocketError wxSocketImpl::SetPeer(GAddress *address)
447 {
448 /* check address */
449 if (address == NULL || address->m_family == wxSOCKET_NOFAMILY)
450 {
451 m_error = wxSOCKET_INVADDR;
452 return wxSOCKET_INVADDR;
453 }
454
455 if (m_peer)
456 GAddress_destroy(m_peer);
457
458 m_peer = GAddress_copy(address);
459
460 return wxSOCKET_NOERROR;
461 }
462
463 GAddress *wxSocketImpl::GetLocal()
464 {
465 GAddress *address;
466 wxSockAddr addr;
467 WX_SOCKLEN_T size = sizeof(addr);
468 wxSocketError err;
469
470 /* try to get it from the m_local var first */
471 if (m_local)
472 return GAddress_copy(m_local);
473
474 /* else, if the socket is initialized, try getsockname */
475 if (m_fd == INVALID_SOCKET)
476 {
477 m_error = wxSOCKET_INVSOCK;
478 return NULL;
479 }
480
481 if (getsockname(m_fd, (sockaddr*)&addr, &size) == SOCKET_ERROR)
482 {
483 m_error = wxSOCKET_IOERR;
484 return NULL;
485 }
486
487 /* got a valid address from getsockname, create a GAddress object */
488 if ((address = GAddress_new()) == NULL)
489 {
490 m_error = wxSOCKET_MEMERR;
491 return NULL;
492 }
493
494 if ((err = _GAddress_translate_from(address, (sockaddr*)&addr, size)) != wxSOCKET_NOERROR)
495 {
496 GAddress_destroy(address);
497 m_error = err;
498 return NULL;
499 }
500
501 return address;
502 }
503
504 GAddress *wxSocketImpl::GetPeer()
505 {
506 /* try to get it from the m_peer var */
507 if (m_peer)
508 return GAddress_copy(m_peer);
509
510 return NULL;
511 }
512
513 // ==========================================================================
514 // wxSocketBase
515 // ==========================================================================
516
517 // --------------------------------------------------------------------------
518 // Initialization and shutdown
519 // --------------------------------------------------------------------------
520
521 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
522 // to m_countInit with a crit section
523 size_t wxSocketBase::m_countInit = 0;
524
525 bool wxSocketBase::IsInitialized()
526 {
527 return m_countInit > 0;
528 }
529
530 bool wxSocketBase::Initialize()
531 {
532 if ( !m_countInit++ )
533 {
534 wxSocketManager * const manager = wxSocketManager::Get();
535 if ( !manager || !manager->OnInit() )
536 {
537 m_countInit--;
538
539 return false;
540 }
541 }
542
543 return true;
544 }
545
546 void wxSocketBase::Shutdown()
547 {
548 // we should be initialized
549 wxASSERT_MSG( m_countInit > 0, _T("extra call to Shutdown()") );
550 if ( --m_countInit == 0 )
551 {
552 wxSocketManager * const manager = wxSocketManager::Get();
553 wxCHECK_RET( manager, "should have a socket manager" );
554
555 manager->OnExit();
556 }
557 }
558
559 // --------------------------------------------------------------------------
560 // Ctor and dtor
561 // --------------------------------------------------------------------------
562
563 void wxSocketBase::Init()
564 {
565 m_impl = NULL;
566 m_type = wxSOCKET_UNINIT;
567
568 // state
569 m_flags = 0;
570 m_connected =
571 m_establishing =
572 m_reading =
573 m_writing =
574 m_error =
575 m_closed = false;
576 m_lcount = 0;
577 m_timeout = 600;
578 m_beingDeleted = false;
579
580 // pushback buffer
581 m_unread = NULL;
582 m_unrd_size = 0;
583 m_unrd_cur = 0;
584
585 // events
586 m_id = wxID_ANY;
587 m_handler = NULL;
588 m_clientData = NULL;
589 m_notify = false;
590 m_eventmask = 0;
591
592 if ( !IsInitialized() )
593 {
594 // this Initialize() will be undone by wxSocketModule::OnExit(), all
595 // the other calls to it should be matched by a call to Shutdown()
596 Initialize();
597 }
598 }
599
600 wxSocketBase::wxSocketBase()
601 {
602 Init();
603 }
604
605 wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
606 {
607 Init();
608
609 SetFlags(flags);
610
611 m_type = type;
612 }
613
614 wxSocketBase::~wxSocketBase()
615 {
616 // Just in case the app called Destroy() *and* then deleted the socket
617 // immediately: don't leave dangling pointers.
618 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
619 if ( traits )
620 traits->RemoveFromPendingDelete(this);
621
622 // Shutdown and close the socket
623 if (!m_beingDeleted)
624 Close();
625
626 // Destroy the implementation object
627 delete m_impl;
628
629 // Free the pushback buffer
630 if (m_unread)
631 free(m_unread);
632 }
633
634 bool wxSocketBase::Destroy()
635 {
636 // Delayed destruction: the socket will be deleted during the next idle
637 // loop iteration. This ensures that all pending events have been
638 // processed.
639 m_beingDeleted = true;
640
641 // Shutdown and close the socket
642 Close();
643
644 // Supress events from now on
645 Notify(false);
646
647 // schedule this object for deletion
648 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
649 if ( traits )
650 {
651 // let the traits object decide what to do with us
652 traits->ScheduleForDestroy(this);
653 }
654 else // no app or no traits
655 {
656 // in wxBase we might have no app object at all, don't leak memory
657 delete this;
658 }
659
660 return true;
661 }
662
663 // ----------------------------------------------------------------------------
664 // simply accessors
665 // ----------------------------------------------------------------------------
666
667 wxSocketError wxSocketBase::LastError() const
668 {
669 return m_impl->GetError();
670 }
671
672 // --------------------------------------------------------------------------
673 // Basic IO calls
674 // --------------------------------------------------------------------------
675
676 // The following IO operations update m_error and m_lcount:
677 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
678 //
679 // TODO: Should Connect, Accept and AcceptWith update m_error?
680
681 bool wxSocketBase::Close()
682 {
683 // Interrupt pending waits
684 InterruptWait();
685
686 if (m_impl)
687 m_impl->Shutdown();
688
689 m_connected = false;
690 m_establishing = false;
691 return true;
692 }
693
694 wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
695 {
696 // Mask read events
697 m_reading = true;
698
699 m_lcount = DoRead(buffer, nbytes);
700
701 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
702 if (m_flags & wxSOCKET_WAITALL)
703 m_error = (m_lcount != nbytes);
704 else
705 m_error = (m_lcount == 0);
706
707 // Allow read events from now on
708 m_reading = false;
709
710 return *this;
711 }
712
713 wxUint32 wxSocketBase::DoRead(void* buffer_, wxUint32 nbytes)
714 {
715 // We use pointer arithmetic here which doesn't work with void pointers.
716 char *buffer = static_cast<char *>(buffer_);
717
718 // Try the push back buffer first, even before checking whether the socket
719 // is valid to allow reading previously pushed back data from an already
720 // closed socket.
721 wxUint32 total = GetPushback(buffer, nbytes, false);
722 nbytes -= total;
723 buffer += total;
724
725 // If it's indeed closed or if read everything, there is nothing more to do.
726 if ( !m_impl || !nbytes )
727 return total;
728
729 wxCHECK_MSG( buffer, 0, "NULL buffer" );
730
731
732 // wxSOCKET_NOWAIT overrides all the other flags and means that we are
733 // polling the socket and don't block at all.
734 if ( m_flags & wxSOCKET_NOWAIT )
735 {
736 wxSocketUnblocker unblock(m_impl);
737 int ret = m_impl->Read(buffer, nbytes);
738 if ( ret < 0 )
739 return 0;
740
741 total += ret;
742 }
743 else // blocking socket
744 {
745 for ( ;; )
746 {
747 // Wait until socket becomes ready for reading dispatching the GUI
748 // events in the meanwhile unless wxSOCKET_BLOCK was explicitly
749 // specified to disable this.
750 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
751 break;
752
753 const int ret = m_impl->Read(buffer, nbytes);
754 if ( ret == 0 )
755 {
756 // for connection-oriented (e.g. TCP) sockets we can only read
757 // 0 bytes if the other end has been closed, and for
758 // connectionless ones (UDP) this flag doesn't make sense
759 // anyhow so we can set it to true too without doing any harm
760 m_closed = true;
761 break;
762 }
763
764 if ( ret < 0 )
765 {
766 // this will be always interpreted as error by Read()
767 return 0;
768 }
769
770 total += ret;
771
772 // If wxSOCKET_WAITALL is not set, we can leave now as we did read
773 // something and we don't need to wait for all nbytes bytes to be
774 // read.
775 if ( !(m_flags & wxSOCKET_WAITALL) )
776 break;
777
778 // Otherwise continue reading until we do read everything.
779 nbytes -= ret;
780 if ( !nbytes )
781 break;
782
783 buffer += ret;
784 }
785 }
786
787 return total;
788 }
789
790 wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
791 {
792 wxUint32 len, len2, sig, total;
793 bool error;
794 int old_flags;
795 struct
796 {
797 unsigned char sig[4];
798 unsigned char len[4];
799 } msg;
800
801 // Mask read events
802 m_reading = true;
803
804 total = 0;
805 error = true;
806 old_flags = m_flags;
807 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
808
809 if (DoRead(&msg, sizeof(msg)) != sizeof(msg))
810 goto exit;
811
812 sig = (wxUint32)msg.sig[0];
813 sig |= (wxUint32)(msg.sig[1] << 8);
814 sig |= (wxUint32)(msg.sig[2] << 16);
815 sig |= (wxUint32)(msg.sig[3] << 24);
816
817 if (sig != 0xfeeddead)
818 {
819 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
820 goto exit;
821 }
822
823 len = (wxUint32)msg.len[0];
824 len |= (wxUint32)(msg.len[1] << 8);
825 len |= (wxUint32)(msg.len[2] << 16);
826 len |= (wxUint32)(msg.len[3] << 24);
827
828 if (len > nbytes)
829 {
830 len2 = len - nbytes;
831 len = nbytes;
832 }
833 else
834 len2 = 0;
835
836 // Don't attempt to read if the msg was zero bytes long.
837 if (len)
838 {
839 total = DoRead(buffer, len);
840
841 if (total != len)
842 goto exit;
843 }
844
845 if (len2)
846 {
847 char *discard_buffer = new char[MAX_DISCARD_SIZE];
848 long discard_len;
849
850 // NOTE: discarded bytes don't add to m_lcount.
851 do
852 {
853 discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
854 discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
855 len2 -= (wxUint32)discard_len;
856 }
857 while ((discard_len > 0) && len2);
858
859 delete [] discard_buffer;
860
861 if (len2 != 0)
862 goto exit;
863 }
864 if (DoRead(&msg, sizeof(msg)) != sizeof(msg))
865 goto exit;
866
867 sig = (wxUint32)msg.sig[0];
868 sig |= (wxUint32)(msg.sig[1] << 8);
869 sig |= (wxUint32)(msg.sig[2] << 16);
870 sig |= (wxUint32)(msg.sig[3] << 24);
871
872 if (sig != 0xdeadfeed)
873 {
874 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
875 goto exit;
876 }
877
878 // everything was OK
879 error = false;
880
881 exit:
882 m_error = error;
883 m_lcount = total;
884 m_reading = false;
885 SetFlags(old_flags);
886
887 return *this;
888 }
889
890 wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
891 {
892 // Mask read events
893 m_reading = true;
894
895 m_lcount = DoRead(buffer, nbytes);
896 Pushback(buffer, m_lcount);
897
898 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
899 if (m_flags & wxSOCKET_WAITALL)
900 m_error = (m_lcount != nbytes);
901 else
902 m_error = (m_lcount == 0);
903
904 // Allow read events again
905 m_reading = false;
906
907 return *this;
908 }
909
910 wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
911 {
912 // Mask write events
913 m_writing = true;
914
915 m_lcount = DoWrite(buffer, nbytes);
916
917 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
918 if (m_flags & wxSOCKET_WAITALL)
919 m_error = (m_lcount != nbytes);
920 else
921 m_error = (m_lcount == 0);
922
923 // Allow write events again
924 m_writing = false;
925
926 return *this;
927 }
928
929 // This function is a mirror image of DoRead() except that it doesn't use the
930 // push back buffer, please see comments there
931 wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
932 {
933 const char *buffer = static_cast<const char *>(buffer_);
934
935 // Return if there is nothing to read or the socket is (already?) closed.
936 if ( !m_impl || !nbytes )
937 return 0;
938
939 wxCHECK_MSG( buffer, 0, "NULL buffer" );
940
941 wxUint32 total = 0;
942 if ( m_flags & wxSOCKET_NOWAIT )
943 {
944 wxSocketUnblocker unblock(m_impl);
945 const int ret = m_impl->Write(buffer, nbytes);
946 if ( ret > 0 )
947 total += ret;
948 }
949 else // blocking socket
950 {
951 for ( ;; )
952 {
953 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
954 break;
955
956 const int ret = m_impl->Write(buffer, nbytes);
957 if ( ret == 0 )
958 {
959 m_closed = true;
960 break;
961 }
962
963 if ( ret < 0 )
964 return 0;
965
966 total += ret;
967 if ( !(m_flags & wxSOCKET_WAITALL) )
968 break;
969
970 nbytes -= ret;
971 if ( !nbytes )
972 break;
973
974 buffer += ret;
975 }
976 }
977
978 return total;
979 }
980
981 wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
982 {
983 wxUint32 total;
984 bool error;
985 struct
986 {
987 unsigned char sig[4];
988 unsigned char len[4];
989 } msg;
990
991 // Mask write events
992 m_writing = true;
993
994 error = true;
995 total = 0;
996 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
997
998 msg.sig[0] = (unsigned char) 0xad;
999 msg.sig[1] = (unsigned char) 0xde;
1000 msg.sig[2] = (unsigned char) 0xed;
1001 msg.sig[3] = (unsigned char) 0xfe;
1002
1003 msg.len[0] = (unsigned char) (nbytes & 0xff);
1004 msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
1005 msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
1006 msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
1007
1008 if (DoWrite(&msg, sizeof(msg)) < sizeof(msg))
1009 goto exit;
1010
1011 total = DoWrite(buffer, nbytes);
1012
1013 if (total < nbytes)
1014 goto exit;
1015
1016 msg.sig[0] = (unsigned char) 0xed;
1017 msg.sig[1] = (unsigned char) 0xfe;
1018 msg.sig[2] = (unsigned char) 0xad;
1019 msg.sig[3] = (unsigned char) 0xde;
1020 msg.len[0] =
1021 msg.len[1] =
1022 msg.len[2] =
1023 msg.len[3] = (char) 0;
1024
1025 if ((DoWrite(&msg, sizeof(msg))) < sizeof(msg))
1026 goto exit;
1027
1028 // everything was OK
1029 error = false;
1030
1031 exit:
1032 m_error = error;
1033 m_lcount = total;
1034 m_writing = false;
1035
1036 return *this;
1037 }
1038
1039 wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
1040 {
1041 if (nbytes != 0)
1042 Pushback(buffer, nbytes);
1043
1044 m_error = false;
1045 m_lcount = nbytes;
1046
1047 return *this;
1048 }
1049
1050 wxSocketBase& wxSocketBase::Discard()
1051 {
1052 char *buffer = new char[MAX_DISCARD_SIZE];
1053 wxUint32 ret;
1054 wxUint32 total = 0;
1055
1056 // Mask read events
1057 m_reading = true;
1058
1059 SetFlags(wxSOCKET_NOWAIT);
1060
1061 do
1062 {
1063 ret = DoRead(buffer, MAX_DISCARD_SIZE);
1064 total += ret;
1065 }
1066 while (ret == MAX_DISCARD_SIZE);
1067
1068 delete[] buffer;
1069 m_lcount = total;
1070 m_error = false;
1071
1072 // Allow read events again
1073 m_reading = false;
1074
1075 return *this;
1076 }
1077
1078 // --------------------------------------------------------------------------
1079 // Wait functions
1080 // --------------------------------------------------------------------------
1081
1082 /*
1083 * Polls the socket to determine its status. This function will
1084 * check for the events specified in the 'flags' parameter, and
1085 * it will return a mask indicating which operations can be
1086 * performed. This function won't block, regardless of the
1087 * mode (blocking | nonblocking) of the socket.
1088 */
1089 wxSocketEventFlags wxSocketImpl::Select(wxSocketEventFlags flags)
1090 {
1091 assert(this);
1092
1093 wxSocketEventFlags result = 0;
1094 fd_set readfds;
1095 fd_set writefds;
1096 fd_set exceptfds;
1097 struct timeval tv;
1098
1099 if (m_fd == -1)
1100 return (wxSOCKET_LOST_FLAG & flags);
1101
1102 /* Do not use a static struct, Linux can garble it */
1103 tv.tv_sec = 0;
1104 tv.tv_usec = 0;
1105
1106 wxFD_ZERO(&readfds);
1107 wxFD_ZERO(&writefds);
1108 wxFD_ZERO(&exceptfds);
1109 wxFD_SET(m_fd, &readfds);
1110 if (flags & wxSOCKET_OUTPUT_FLAG || flags & wxSOCKET_CONNECTION_FLAG)
1111 wxFD_SET(m_fd, &writefds);
1112 wxFD_SET(m_fd, &exceptfds);
1113
1114 /* Check 'sticky' CONNECTION flag first */
1115 result |= wxSOCKET_CONNECTION_FLAG & m_detected;
1116
1117 /* If we have already detected a LOST event, then don't try
1118 * to do any further processing.
1119 */
1120 if ((m_detected & wxSOCKET_LOST_FLAG) != 0)
1121 {
1122 m_establishing = false;
1123 return (wxSOCKET_LOST_FLAG & flags);
1124 }
1125
1126 /* Try select now */
1127 if (select(m_fd + 1, &readfds, &writefds, &exceptfds, &tv) < 0)
1128 {
1129 /* What to do here? */
1130 return (result & flags);
1131 }
1132
1133 /* Check for exceptions and errors */
1134 if (wxFD_ISSET(m_fd, &exceptfds))
1135 {
1136 m_establishing = false;
1137 m_detected = wxSOCKET_LOST_FLAG;
1138
1139 /* LOST event: Abort any further processing */
1140 return (wxSOCKET_LOST_FLAG & flags);
1141 }
1142
1143 /* Check for readability */
1144 if (wxFD_ISSET(m_fd, &readfds))
1145 {
1146 result |= wxSOCKET_INPUT_FLAG;
1147
1148 if (m_server && m_stream)
1149 {
1150 /* This is a TCP server socket that detected a connection.
1151 While the INPUT_FLAG is also set, it doesn't matter on
1152 this kind of sockets, as we can only Accept() from them. */
1153 m_detected |= wxSOCKET_CONNECTION_FLAG;
1154 }
1155 }
1156
1157 /* Check for writability */
1158 if (wxFD_ISSET(m_fd, &writefds))
1159 {
1160 if (m_establishing && !m_server)
1161 {
1162 int error;
1163 SOCKOPTLEN_T len = sizeof(error);
1164 m_establishing = false;
1165 getsockopt(m_fd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
1166
1167 if (error)
1168 {
1169 m_detected = wxSOCKET_LOST_FLAG;
1170
1171 /* LOST event: Abort any further processing */
1172 return (wxSOCKET_LOST_FLAG & flags);
1173 }
1174 else
1175 {
1176 m_detected |= wxSOCKET_CONNECTION_FLAG;
1177 }
1178 }
1179 else
1180 {
1181 result |= wxSOCKET_OUTPUT_FLAG;
1182 }
1183 }
1184
1185 return (result | m_detected) & flags;
1186 }
1187
1188 // All Wait functions poll the socket using Select() to
1189 // check for the specified combination of conditions, until one
1190 // of these conditions become true, an error occurs, or the
1191 // timeout elapses. The polling loop runs the event loop so that
1192 // this won't block the GUI.
1193
1194 bool
1195 wxSocketBase::DoWait(long seconds, long milliseconds, wxSocketEventFlags flags)
1196 {
1197 wxCHECK_MSG( m_impl, false, "can't wait on invalid socket" );
1198
1199 // This can be set to true from Interrupt() to exit this function a.s.a.p.
1200 m_interrupt = false;
1201
1202
1203 // Use either the provided timeout or the default timeout value associated
1204 // with this socket.
1205 //
1206 // TODO: allow waiting forever, see #9443
1207 const long timeout = seconds == -1 ? m_timeout * 1000
1208 : seconds * 1000 + milliseconds;
1209 const wxMilliClock_t timeEnd = wxGetLocalTimeMillis() + timeout;
1210
1211 // Get the active event loop which we'll use for the message dispatching
1212 // when running in the main thread
1213 wxEventLoopBase *eventLoop;
1214 if ( wxIsMainThread() )
1215 {
1216 eventLoop = wxEventLoop::GetActive();
1217 }
1218 else // in worker thread
1219 {
1220 // We never dispatch messages from threads other than the main one.
1221 eventLoop = NULL;
1222 }
1223
1224 // Wait in an active polling loop: notice that the loop is executed at
1225 // least once, even if timeout is 0 (i.e. polling).
1226 bool gotEvent = false;
1227 for ( ;; )
1228 {
1229 // We always stop waiting when the connection is lost as it doesn't
1230 // make sense to continue further, even if wxSOCKET_LOST_FLAG is not
1231 // specified in flags to wait for.
1232 const wxSocketEventFlags
1233 result = m_impl->Select(flags | wxSOCKET_LOST_FLAG);
1234
1235 // Incoming connection (server) or connection established (client)?
1236 if ( result & wxSOCKET_CONNECTION_FLAG )
1237 {
1238 m_connected = true;
1239 m_establishing = false;
1240 gotEvent = true;
1241 break;
1242 }
1243
1244 // Data available or output buffer ready?
1245 if ( (result & wxSOCKET_INPUT_FLAG) || (result & wxSOCKET_OUTPUT_FLAG) )
1246 {
1247 gotEvent = true;
1248 break;
1249 }
1250
1251 // Connection lost
1252 if ( result & wxSOCKET_LOST_FLAG )
1253 {
1254 m_connected = false;
1255 m_establishing = false;
1256 if ( flags & wxSOCKET_LOST_FLAG )
1257 gotEvent = true;
1258 break;
1259 }
1260
1261 if ( m_interrupt )
1262 break;
1263
1264 // Wait more?
1265 const wxMilliClock_t timeNow = wxGetLocalTimeMillis();
1266 if ( timeNow >= timeEnd )
1267 break;
1268
1269 if ( eventLoop )
1270 {
1271 // This function is only called if wxSOCKET_BLOCK flag was not used
1272 // and so we should dispatch the events if there is an event loop
1273 // capable of doing it.
1274 if ( eventLoop->Pending() )
1275 eventLoop->Dispatch();
1276 }
1277 #if wxUSE_THREADS
1278 else // no event loop or waiting in another thread
1279 {
1280 // We're busy waiting but at least give up the rest of our current
1281 // time slice.
1282 wxThread::Yield();
1283 }
1284 #endif // wxUSE_THREADS
1285 }
1286
1287 return gotEvent;
1288 }
1289
1290 bool wxSocketBase::Wait(long seconds, long milliseconds)
1291 {
1292 return DoWait(seconds, milliseconds,
1293 wxSOCKET_INPUT_FLAG |
1294 wxSOCKET_OUTPUT_FLAG |
1295 wxSOCKET_CONNECTION_FLAG |
1296 wxSOCKET_LOST_FLAG
1297 );
1298 }
1299
1300 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
1301 {
1302 // Check pushback buffer before entering DoWait
1303 if ( m_unread )
1304 return true;
1305
1306 // Note that wxSOCKET_INPUT_LOST has to be explicitly passed to DoWait
1307 // because of the semantics of WaitForRead: a return value of true means
1308 // that a Read call will return immediately, not that there is
1309 // actually data to read.
1310 return DoWait(seconds, milliseconds, wxSOCKET_INPUT_FLAG | wxSOCKET_LOST_FLAG);
1311 }
1312
1313
1314 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
1315 {
1316 return DoWait(seconds, milliseconds, wxSOCKET_OUTPUT_FLAG | wxSOCKET_LOST_FLAG);
1317 }
1318
1319 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
1320 {
1321 return DoWait(seconds, milliseconds, wxSOCKET_LOST_FLAG);
1322 }
1323
1324 // --------------------------------------------------------------------------
1325 // Miscellaneous
1326 // --------------------------------------------------------------------------
1327
1328 //
1329 // Get local or peer address
1330 //
1331
1332 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
1333 {
1334 GAddress *peer;
1335
1336 if (!m_impl)
1337 return false;
1338
1339 peer = m_impl->GetPeer();
1340
1341 // copying a null address would just trigger an assert anyway
1342
1343 if (!peer)
1344 return false;
1345
1346 addr_man.SetAddress(peer);
1347 GAddress_destroy(peer);
1348
1349 return true;
1350 }
1351
1352 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
1353 {
1354 GAddress *local;
1355
1356 if (!m_impl)
1357 return false;
1358
1359 local = m_impl->GetLocal();
1360 addr_man.SetAddress(local);
1361 GAddress_destroy(local);
1362
1363 return true;
1364 }
1365
1366 //
1367 // Save and restore socket state
1368 //
1369
1370 void wxSocketBase::SaveState()
1371 {
1372 wxSocketState *state;
1373
1374 state = new wxSocketState();
1375
1376 state->m_flags = m_flags;
1377 state->m_notify = m_notify;
1378 state->m_eventmask = m_eventmask;
1379 state->m_clientData = m_clientData;
1380
1381 m_states.Append(state);
1382 }
1383
1384 void wxSocketBase::RestoreState()
1385 {
1386 wxList::compatibility_iterator node;
1387 wxSocketState *state;
1388
1389 node = m_states.GetLast();
1390 if (!node)
1391 return;
1392
1393 state = (wxSocketState *)node->GetData();
1394
1395 m_flags = state->m_flags;
1396 m_notify = state->m_notify;
1397 m_eventmask = state->m_eventmask;
1398 m_clientData = state->m_clientData;
1399
1400 m_states.Erase(node);
1401 delete state;
1402 }
1403
1404 //
1405 // Timeout and flags
1406 //
1407
1408 void wxSocketBase::SetTimeout(long seconds)
1409 {
1410 m_timeout = seconds;
1411
1412 if (m_impl)
1413 m_impl->SetTimeout(m_timeout * 1000);
1414 }
1415
1416 void wxSocketBase::SetFlags(wxSocketFlags flags)
1417 {
1418 // Do some sanity checking on the flags used: not all values can be used
1419 // together.
1420 wxASSERT_MSG( !(flags & wxSOCKET_NOWAIT) ||
1421 !(flags & (wxSOCKET_WAITALL | wxSOCKET_BLOCK)),
1422 "Using wxSOCKET_WAITALL or wxSOCKET_BLOCK with "
1423 "wxSOCKET_NOWAIT doesn't make sense" );
1424
1425 m_flags = flags;
1426 }
1427
1428
1429 // --------------------------------------------------------------------------
1430 // Event handling
1431 // --------------------------------------------------------------------------
1432
1433 void wxSocketBase::OnRequest(wxSocketNotify notification)
1434 {
1435 switch(notification)
1436 {
1437 case wxSOCKET_CONNECTION:
1438 m_establishing = false;
1439 m_connected = true;
1440 break;
1441
1442 // If we are in the middle of a R/W operation, do not
1443 // propagate events to users. Also, filter 'late' events
1444 // which are no longer valid.
1445
1446 case wxSOCKET_INPUT:
1447 if (m_reading || !m_impl->Select(wxSOCKET_INPUT_FLAG))
1448 return;
1449 break;
1450
1451 case wxSOCKET_OUTPUT:
1452 if (m_writing || !m_impl->Select(wxSOCKET_OUTPUT_FLAG))
1453 return;
1454 break;
1455
1456 case wxSOCKET_LOST:
1457 m_connected = false;
1458 m_establishing = false;
1459 break;
1460
1461 case wxSOCKET_MAX_EVENT:
1462 wxFAIL_MSG( "unexpected notification" );
1463 return;
1464 }
1465
1466 // Schedule the event
1467
1468 wxSocketEventFlags flag = 0;
1469 wxUnusedVar(flag);
1470 switch (notification)
1471 {
1472 case wxSOCKET_INPUT: flag = wxSOCKET_INPUT_FLAG; break;
1473 case wxSOCKET_OUTPUT: flag = wxSOCKET_OUTPUT_FLAG; break;
1474 case wxSOCKET_CONNECTION: flag = wxSOCKET_CONNECTION_FLAG; break;
1475 case wxSOCKET_LOST: flag = wxSOCKET_LOST_FLAG; break;
1476 default:
1477 wxLogWarning(_("wxSocket: unknown event!."));
1478 return;
1479 }
1480
1481 if (((m_eventmask & flag) == flag) && m_notify)
1482 {
1483 if (m_handler)
1484 {
1485 wxSocketEvent event(m_id);
1486 event.m_event = notification;
1487 event.m_clientData = m_clientData;
1488 event.SetEventObject(this);
1489
1490 m_handler->AddPendingEvent(event);
1491 }
1492 }
1493 }
1494
1495 void wxSocketBase::Notify(bool notify)
1496 {
1497 m_notify = notify;
1498 if (m_impl)
1499 m_impl->Notify(notify);
1500 }
1501
1502 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1503 {
1504 m_eventmask = flags;
1505 }
1506
1507 void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1508 {
1509 m_handler = &handler;
1510 m_id = id;
1511 }
1512
1513 // --------------------------------------------------------------------------
1514 // Pushback buffer
1515 // --------------------------------------------------------------------------
1516
1517 void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1518 {
1519 if (!size) return;
1520
1521 if (m_unread == NULL)
1522 m_unread = malloc(size);
1523 else
1524 {
1525 void *tmp;
1526
1527 tmp = malloc(m_unrd_size + size);
1528 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1529 free(m_unread);
1530
1531 m_unread = tmp;
1532 }
1533
1534 m_unrd_size += size;
1535
1536 memcpy(m_unread, buffer, size);
1537 }
1538
1539 wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1540 {
1541 wxCHECK_MSG( buffer, 0, "NULL buffer" );
1542
1543 if (!m_unrd_size)
1544 return 0;
1545
1546 if (size > (m_unrd_size-m_unrd_cur))
1547 size = m_unrd_size-m_unrd_cur;
1548
1549 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1550
1551 if (!peek)
1552 {
1553 m_unrd_cur += size;
1554 if (m_unrd_size == m_unrd_cur)
1555 {
1556 free(m_unread);
1557 m_unread = NULL;
1558 m_unrd_size = 0;
1559 m_unrd_cur = 0;
1560 }
1561 }
1562
1563 return size;
1564 }
1565
1566
1567 // ==========================================================================
1568 // wxSocketServer
1569 // ==========================================================================
1570
1571 // --------------------------------------------------------------------------
1572 // Ctor
1573 // --------------------------------------------------------------------------
1574
1575 wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
1576 wxSocketFlags flags)
1577 : wxSocketBase(flags, wxSOCKET_SERVER)
1578 {
1579 wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
1580
1581 m_impl = wxSocketImpl::Create(*this);
1582
1583 if (!m_impl)
1584 {
1585 wxLogTrace( wxTRACE_Socket, _T("*** Failed to create m_impl") );
1586 return;
1587 }
1588
1589 // Setup the socket as server
1590 m_impl->Notify(m_notify);
1591 m_impl->SetLocal(addr_man.GetAddress());
1592
1593 if (GetFlags() & wxSOCKET_REUSEADDR) {
1594 m_impl->SetReusable();
1595 }
1596 if (GetFlags() & wxSOCKET_BROADCAST) {
1597 m_impl->SetBroadcast();
1598 }
1599 if (GetFlags() & wxSOCKET_NOBIND) {
1600 m_impl->DontDoBind();
1601 }
1602
1603 if (m_impl->CreateServer() != wxSOCKET_NOERROR)
1604 {
1605 delete m_impl;
1606 m_impl = NULL;
1607
1608 wxLogTrace( wxTRACE_Socket, _T("*** CreateServer() failed") );
1609 return;
1610 }
1611
1612 wxLogTrace( wxTRACE_Socket, _T("wxSocketServer on fd %d"), m_impl->m_fd );
1613 }
1614
1615 // --------------------------------------------------------------------------
1616 // Accept
1617 // --------------------------------------------------------------------------
1618
1619 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1620 {
1621 if (!m_impl)
1622 return false;
1623
1624 // If wait == false, then the call should be nonblocking.
1625 // When we are finished, we put the socket to blocking mode
1626 // again.
1627 wxSocketUnblocker unblock(m_impl, !wait);
1628 sock.m_impl = m_impl->WaitConnection(sock);
1629
1630 if ( !sock.m_impl )
1631 return false;
1632
1633 sock.m_type = wxSOCKET_BASE;
1634 sock.m_connected = true;
1635
1636 return true;
1637 }
1638
1639 wxSocketBase *wxSocketServer::Accept(bool wait)
1640 {
1641 wxSocketBase* sock = new wxSocketBase();
1642
1643 sock->SetFlags(m_flags);
1644
1645 if (!AcceptWith(*sock, wait))
1646 {
1647 sock->Destroy();
1648 sock = NULL;
1649 }
1650
1651 return sock;
1652 }
1653
1654 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1655 {
1656 return DoWait(seconds, milliseconds, wxSOCKET_CONNECTION_FLAG);
1657 }
1658
1659 bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1660 {
1661 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1662
1663 SOCKOPTLEN_T lenreal;
1664 if ( getsockopt(m_impl->m_fd, level, optname,
1665 static_cast<char *>(optval), &lenreal) != 0 )
1666 return false;
1667
1668 *optlen = lenreal;
1669
1670 return true;
1671 }
1672
1673 bool
1674 wxSocketBase::SetOption(int level, int optname, const void *optval, int optlen)
1675 {
1676 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1677
1678 return setsockopt(m_impl->m_fd, level, optname,
1679 static_cast<const char *>(optval), optlen) == 0;
1680 }
1681
1682 bool wxSocketBase::SetLocal(const wxIPV4address& local)
1683 {
1684 GAddress* la = local.GetAddress();
1685
1686 // If the address is valid, save it for use when we call Connect
1687 if (la && la->m_addr)
1688 {
1689 m_localAddress = local;
1690
1691 return true;
1692 }
1693
1694 return false;
1695 }
1696
1697 // ==========================================================================
1698 // wxSocketClient
1699 // ==========================================================================
1700
1701 // --------------------------------------------------------------------------
1702 // Ctor and dtor
1703 // --------------------------------------------------------------------------
1704
1705 wxSocketClient::wxSocketClient(wxSocketFlags flags)
1706 : wxSocketBase(flags, wxSOCKET_CLIENT)
1707 {
1708 m_initialRecvBufferSize =
1709 m_initialSendBufferSize = -1;
1710 }
1711
1712 wxSocketClient::~wxSocketClient()
1713 {
1714 }
1715
1716 // --------------------------------------------------------------------------
1717 // Connect
1718 // --------------------------------------------------------------------------
1719
1720 bool wxSocketClient::DoConnect(const wxSockAddress& addr_man,
1721 const wxSockAddress* local,
1722 bool wait)
1723 {
1724 if (m_impl)
1725 {
1726 // Shutdown and destroy the socket
1727 Close();
1728 delete m_impl;
1729 }
1730
1731 m_impl = wxSocketImpl::Create(*this);
1732 m_connected = false;
1733 m_establishing = false;
1734
1735 if (!m_impl)
1736 return false;
1737
1738 // If wait == false, then the call should be nonblocking. When we are
1739 // finished, we put the socket to blocking mode again.
1740 wxSocketUnblocker unblock(m_impl, !wait);
1741
1742 // Reuse makes sense for clients too, if we are trying to rebind to the same port
1743 if (GetFlags() & wxSOCKET_REUSEADDR)
1744 {
1745 m_impl->SetReusable();
1746 }
1747 if (GetFlags() & wxSOCKET_BROADCAST)
1748 {
1749 m_impl->SetBroadcast();
1750 }
1751 if (GetFlags() & wxSOCKET_NOBIND)
1752 {
1753 m_impl->DontDoBind();
1754 }
1755
1756 // If no local address was passed and one has been set, use the one that was Set
1757 if (!local && m_localAddress.GetAddress())
1758 {
1759 local = &m_localAddress;
1760 }
1761
1762 // Bind to the local IP address and port, when provided
1763 if (local)
1764 {
1765 GAddress* la = local->GetAddress();
1766
1767 if (la && la->m_addr)
1768 m_impl->SetLocal(la);
1769 }
1770
1771 m_impl->SetInitialSocketBuffers(m_initialRecvBufferSize, m_initialSendBufferSize);
1772
1773 m_impl->SetPeer(addr_man.GetAddress());
1774 const wxSocketError err = m_impl->CreateClient();
1775
1776 //this will register for callbacks - must be called after m_impl->m_fd was initialized
1777 m_impl->Notify(m_notify);
1778
1779 if (err != wxSOCKET_NOERROR)
1780 {
1781 if (err == wxSOCKET_WOULDBLOCK)
1782 m_establishing = true;
1783
1784 return false;
1785 }
1786
1787 m_connected = true;
1788 return true;
1789 }
1790
1791 bool wxSocketClient::Connect(const wxSockAddress& addr_man, bool wait)
1792 {
1793 return DoConnect(addr_man, NULL, wait);
1794 }
1795
1796 bool wxSocketClient::Connect(const wxSockAddress& addr_man,
1797 const wxSockAddress& local,
1798 bool wait)
1799 {
1800 return DoConnect(addr_man, &local, wait);
1801 }
1802
1803 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1804 {
1805 if ( m_connected )
1806 {
1807 // this happens if the initial attempt to connect succeeded without
1808 // blocking
1809 return true;
1810 }
1811
1812 wxCHECK_MSG( m_establishing && m_impl, false,
1813 "No connection establishment attempt in progress" );
1814
1815 // we must specify wxSOCKET_LOST_FLAG here explicitly because we must return
1816 // true if the connection establishment process is finished, whether it is
1817 // over because we successfully connected or because we were not able to
1818 // connect
1819 return DoWait(seconds, milliseconds,
1820 wxSOCKET_CONNECTION_FLAG | wxSOCKET_LOST_FLAG);
1821 }
1822
1823 // ==========================================================================
1824 // wxDatagramSocket
1825 // ==========================================================================
1826
1827 wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
1828 wxSocketFlags flags )
1829 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
1830 {
1831 // Create the socket
1832 m_impl = wxSocketImpl::Create(*this);
1833
1834 if (!m_impl)
1835 return;
1836
1837 m_impl->Notify(m_notify);
1838 // Setup the socket as non connection oriented
1839 m_impl->SetLocal(addr.GetAddress());
1840 if (flags & wxSOCKET_REUSEADDR)
1841 {
1842 m_impl->SetReusable();
1843 }
1844 if (GetFlags() & wxSOCKET_BROADCAST)
1845 {
1846 m_impl->SetBroadcast();
1847 }
1848 if (GetFlags() & wxSOCKET_NOBIND)
1849 {
1850 m_impl->DontDoBind();
1851 }
1852
1853 if ( m_impl->CreateUDP() != wxSOCKET_NOERROR )
1854 {
1855 delete m_impl;
1856 m_impl = NULL;
1857 return;
1858 }
1859
1860 // Initialize all stuff
1861 m_connected = false;
1862 m_establishing = false;
1863 }
1864
1865 wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
1866 void* buf,
1867 wxUint32 nBytes )
1868 {
1869 Read(buf, nBytes);
1870 GetPeer(addr);
1871 return (*this);
1872 }
1873
1874 wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
1875 const void* buf,
1876 wxUint32 nBytes )
1877 {
1878 wxASSERT_MSG( m_impl, _T("Socket not initialised") );
1879
1880 m_impl->SetPeer(addr.GetAddress());
1881 Write(buf, nBytes);
1882 return (*this);
1883 }
1884
1885 // ==========================================================================
1886 // wxSocketModule
1887 // ==========================================================================
1888
1889 class wxSocketModule : public wxModule
1890 {
1891 public:
1892 virtual bool OnInit()
1893 {
1894 // wxSocketBase will call Initialize() itself only if sockets are
1895 // really used, don't do it from here
1896 return true;
1897 }
1898
1899 virtual void OnExit()
1900 {
1901 if ( wxSocketBase::IsInitialized() )
1902 wxSocketBase::Shutdown();
1903 }
1904
1905 private:
1906 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1907 };
1908
1909 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1910
1911 #endif // wxUSE_SOCKETS