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