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