]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
56f16ce2e5ff341a22a9b5d283f47b1e3ce7c884
[wxWidgets.git] / src / common / socket.cpp
1 ////////////////////////////////////////////////////////////////////////////////
2 // Name: socket.cpp
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux
5 // Created: April 1997
6 // Updated: July 1999
7 // Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
8 // RCS_ID: $Id$
9 // License: see wxWindows license
10 ////////////////////////////////////////////////////////////////////////////////
11 #ifdef __GNUG__
12 #pragma implementation "socket.h"
13 #endif
14
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
17
18 #ifdef __BORLANDC__
19 #pragma hdrstop
20 #endif
21
22 #if wxUSE_SOCKETS
23
24 /////////////////////////////////////////////////////////////////////////////
25 // wxWindows headers
26 /////////////////////////////////////////////////////////////////////////////
27 #include <wx/defs.h>
28 #include <wx/object.h>
29 #include <wx/string.h>
30 #include <wx/timer.h>
31 #include <wx/utils.h>
32 #include <wx/log.h>
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37
38 /////////////////////////////////////////////////////////////////////////////
39 // wxSocket headers
40 /////////////////////////////////////////////////////////////////////////////
41 #include <wx/module.h>
42 #include <wx/sckaddr.h>
43 #include <wx/socket.h>
44
45 // --------------------------------------------------------------
46 // ClassInfos
47 // --------------------------------------------------------------
48 #if !USE_SHARED_LIBRARY
49 IMPLEMENT_CLASS(wxSocketBase, wxObject)
50 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
51 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
52 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
53 #endif
54
55 class wxSocketState : public wxObject {
56 public:
57 bool notify_state;
58 GSocketEventFlags evt_notify_state;
59 wxSocketBase::wxSockFlags socket_flags;
60 wxSocketBase::wxSockCbk c_callback;
61 char *c_callback_data;
62
63 public:
64 wxSocketState() : wxObject() {}
65 };
66
67 // --------------------------------------------------------------
68 // --------- wxSocketBase CONSTRUCTOR ---------------------------
69 // --------------------------------------------------------------
70 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
71 wxSocketBase::wxSockType _type) :
72 wxEvtHandler(),
73 m_socket(NULL), m_flags(_flags), m_type(_type),
74 m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
75 m_lcount(0), m_timeout(3600),
76 m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
77 m_cbk(NULL), m_cdata(NULL),
78 m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
79 m_defering(NO_DEFER),
80 m_states()
81 {
82 }
83
84 wxSocketBase::wxSocketBase() :
85 wxEvtHandler(),
86 m_socket(NULL), m_flags(SPEED | WAITALL), m_type(SOCK_UNINIT),
87 m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
88 m_lcount(0), m_timeout(3600),
89 m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
90 m_cbk(NULL), m_cdata(NULL),
91 m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
92 m_defering(NO_DEFER),
93 m_states()
94 {
95 }
96
97 // --------------------------------------------------------------
98 // wxSocketBase destructor
99 // --------------------------------------------------------------
100
101 wxSocketBase::~wxSocketBase()
102 {
103 if (m_unread)
104 free(m_unread);
105
106 // At last, close the file descriptor.
107 Close();
108
109 if (m_socket)
110 GSocket_destroy(m_socket);
111 }
112
113 bool wxSocketBase::Close()
114 {
115 if (m_socket)
116 {
117 if (m_notify_state == TRUE)
118 Notify(FALSE);
119
120 // Shutdown the connection.
121 GSocket_Shutdown(m_socket);
122 m_connected = FALSE;
123 }
124
125 return TRUE;
126 }
127
128 // --------------------------------------------------------------
129 // wxSocketBase base IO function
130 // --------------------------------------------------------------
131
132 int wxSocketBase::DeferRead(char *buffer, size_t nbytes)
133 {
134 GSocketEventFlags old_event_flags;
135 bool old_notify_state;
136
137 wxASSERT(m_defering == NO_DEFER);
138
139 m_defering = DEFER_READ;
140
141 old_event_flags = NeededReq();
142 old_notify_state = m_notify_state;
143
144 SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
145 Notify(TRUE);
146
147 m_defer_buffer = buffer;
148 m_defer_nbytes = nbytes;
149 while (m_defer_buffer != NULL)
150 wxYield();
151
152 Notify(old_notify_state);
153 SetNotify(old_event_flags);
154
155 m_defering = NO_DEFER;
156
157 return nbytes-m_defer_nbytes;
158 }
159
160 wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
161 {
162 int ret = 1;
163
164 m_lcount = GetPushback(buffer, nbytes, FALSE);
165 nbytes -= m_lcount;
166 buffer += m_lcount;
167
168 if (!m_connected)
169 return *this;
170
171 // If we have got the whole needed buffer or if we don't want to
172 // wait then it returns immediately.
173 if (!nbytes || (m_lcount && !(m_flags & WAITALL)) ) {
174 return *this;
175 }
176
177 if ((m_flags & SPEED) != 0) {
178
179 if ((m_flags & WAITALL) != 0) {
180 while (ret > 0 && nbytes > 0) {
181 ret = GSocket_Read(m_socket, buffer, nbytes);
182 m_lcount += ret;
183 buffer += ret;
184 nbytes -= ret;
185 }
186 // In case the last call was an error ...
187 if (ret < 0)
188 m_lcount ++;
189 } else {
190 ret = GSocket_Read(m_socket, buffer, nbytes);
191 if (ret > 0)
192 m_lcount += ret;
193 }
194
195 } else {
196 ret = DeferRead(buffer, nbytes);
197
198 if (ret > 0)
199 m_lcount += ret;
200 }
201
202 return *this;
203 }
204
205 wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
206 {
207 unsigned long len, len2, sig;
208 struct {
209 char sig[4];
210 char len[4];
211 } msg;
212
213 // sig should be an explicit 32-bit unsigned integer; I've seen
214 // compilers in which size_t was actually a 16-bit unsigned integer
215
216 Read((char *)&msg, sizeof(msg));
217 if (m_lcount != sizeof(msg))
218 return *this;
219
220 sig = msg.sig[0] & 0xff;
221 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
222 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
223 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
224
225 if (sig != 0xfeeddead)
226 return *this;
227 len = msg.len[0] & 0xff;
228 len |= (size_t)(msg.len[1] & 0xff) << 8;
229 len |= (size_t)(msg.len[2] & 0xff) << 16;
230 len |= (size_t)(msg.len[3] & 0xff) << 24;
231
232 // len2 is incorrectly computed in the original; this sequence is
233 // the fix
234 if (len > nbytes) {
235 len2 = len - nbytes;
236 len = nbytes;
237 }
238 else
239 len2 = 0;
240
241 // the "len &&" in the following statement is necessary so that
242 // we don't attempt to read (and possibly hang the system)
243 // if the message was zero bytes long
244 if (len && Read(buffer, len).LastCount() != len)
245 return *this;
246 if (len2 && (Read(NULL, len2).LastCount() != len2))
247 return *this;
248 if (Read((char *)&msg, sizeof(msg)).LastCount() != sizeof(msg))
249 return *this;
250
251 sig = msg.sig[0] & 0xff;
252 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
253 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
254 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
255
256 // ERROR
257 if (sig != 0xdeadfeed)
258 wxLogDebug(_T("Warning: invalid signature returned to ReadMsg\n"));
259
260 return *this;
261 }
262
263 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
264 {
265 Read(buffer, nbytes);
266 CreatePushbackAfter(buffer, nbytes);
267
268 return *this;
269 }
270
271 int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes)
272 {
273 GSocketEventFlags old_event_flags;
274 bool old_notify_state;
275
276 wxASSERT(m_defering == NO_DEFER);
277
278 m_defering = DEFER_WRITE;
279
280 old_event_flags = NeededReq();
281 old_notify_state = m_notify_state;
282
283 SetNotify(GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
284 Notify(TRUE);
285
286 m_defer_buffer = (char *)buffer;
287 m_defer_nbytes = nbytes;
288 while (m_defer_buffer != NULL)
289 wxYield();
290
291 Notify(old_notify_state);
292 SetNotify(old_event_flags);
293
294 m_defering = NO_DEFER;
295
296 return nbytes-m_defer_nbytes;
297 }
298
299 wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
300 {
301 int ret;
302
303 if ((m_flags & SPEED) != 0)
304 ret = GSocket_Write(m_socket, buffer, nbytes);
305 else
306 ret = DeferWrite(buffer, nbytes);
307
308 if (ret != -1)
309 m_lcount += ret;
310
311 return *this;
312 }
313
314 wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
315 {
316 struct {
317 char sig[4];
318 char len[4];
319 } msg;
320
321 // warning about 'cast truncates constant value'
322 #ifdef __VISUALC__
323 #pragma warning(disable: 4310)
324 #endif // __VISUALC__
325
326 msg.sig[0] = (char) 0xad;
327 msg.sig[1] = (char) 0xde;
328 msg.sig[2] = (char) 0xed;
329 msg.sig[3] = (char) 0xfe;
330
331 msg.len[0] = (char) nbytes & 0xff;
332 msg.len[1] = (char) (nbytes >> 8) & 0xff;
333 msg.len[2] = (char) (nbytes >> 16) & 0xff;
334 msg.len[3] = (char) (nbytes >> 24) & 0xff;
335
336 if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
337 return *this;
338 if (Write(buffer, nbytes).LastCount() < nbytes)
339 return *this;
340
341 msg.sig[0] = (char) 0xed;
342 msg.sig[1] = (char) 0xfe;
343 msg.sig[2] = (char) 0xad;
344 msg.sig[3] = (char) 0xde;
345 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
346 Write((char *)&msg, sizeof(msg));
347
348 return *this;
349
350 #ifdef __VISUALC__
351 #pragma warning(default: 4310)
352 #endif // __VISUALC__
353 }
354
355 wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
356 {
357 m_lcount = 0;
358 if (nbytes != 0) {
359 CreatePushbackAfter(buffer, nbytes);
360 m_lcount = nbytes;
361 }
362 return *this;
363 }
364
365 bool wxSocketBase::IsData() const
366 {
367 if (!m_socket)
368 return FALSE;
369
370 return (GSocket_DataAvailable(m_socket));
371 }
372
373 void wxSocketBase::DoDefer(GSocketEvent req_evt)
374 {
375 int ret;
376
377 if (req_evt == GSOCK_LOST) {
378 Close();
379 m_defer_buffer = NULL;
380 return;
381 }
382 switch (m_defering) {
383 case DEFER_READ:
384 ret = GSocket_Read(m_socket, m_defer_buffer, m_defer_nbytes);
385 break;
386 case DEFER_WRITE:
387 ret = GSocket_Write(m_socket, m_defer_buffer, m_defer_nbytes);
388 break;
389 default:
390 ret = -1;
391 break;
392 }
393
394 m_defer_nbytes -= ret;
395
396 if (ret < 0)
397 m_defer_nbytes++;
398
399 if ((m_flags & WAITALL) == 0 || m_defer_nbytes == 0 || ret < 0) {
400 m_defer_buffer = NULL;
401 Notify(FALSE);
402 } else
403 m_defer_buffer += ret;
404 }
405
406 // ---------------------------------------------------------------------
407 // --------- wxSocketBase Discard(): deletes all byte in the input queue
408 // ---------------------------------------------------------------------
409 void wxSocketBase::Discard()
410 {
411 #define MAX_BUFSIZE (10*1024)
412 char *my_data = new char[MAX_BUFSIZE];
413 size_t recv_size = MAX_BUFSIZE;
414
415 SaveState();
416 SetFlags(NOWAIT | SPEED);
417
418 while (recv_size == MAX_BUFSIZE)
419 {
420 recv_size = Read(my_data, MAX_BUFSIZE).LastCount();
421 }
422
423 RestoreState();
424 delete [] my_data;
425
426 #undef MAX_BUFSIZE
427 }
428
429 // --------------------------------------------------------------
430 // wxSocketBase socket info functions
431 // --------------------------------------------------------------
432
433 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
434 {
435 GAddress *peer;
436
437 if (!m_socket)
438 return FALSE;
439
440 peer = GSocket_GetPeer(m_socket);
441 addr_man.SetAddress(peer);
442 GAddress_destroy(peer);
443
444 return TRUE;
445 }
446
447 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
448 {
449 GAddress *local;
450
451 if (!m_socket)
452 return FALSE;
453
454 local = GSocket_GetLocal(m_socket);
455 addr_man.SetAddress(local);
456 GAddress_destroy(local);
457
458 return TRUE;
459 }
460
461 // --------------------------------------------------------------
462 // wxSocketBase wait functions
463 // --------------------------------------------------------------
464
465 void wxSocketBase::SaveState()
466 {
467 wxSocketState *state;
468
469 state = new wxSocketState();
470
471 state->notify_state = m_notify_state;
472 state->evt_notify_state = m_neededreq;
473 state->socket_flags = m_flags;
474 state->c_callback = m_cbk;
475 state->c_callback_data = m_cdata;
476
477 m_states.Append(state);
478 }
479
480 void wxSocketBase::RestoreState()
481 {
482 wxNode *node;
483 wxSocketState *state;
484
485 node = m_states.Last();
486 if (!node)
487 return;
488
489 state = (wxSocketState *)node->Data();
490
491 SetFlags(state->socket_flags);
492 m_neededreq = state->evt_notify_state;
493 m_cbk = state->c_callback;
494 m_cdata = state->c_callback_data;
495 Notify(state->notify_state);
496
497 delete node;
498 delete state;
499 }
500
501 // --------------------------------------------------------------
502 // --------- wxSocketBase callback functions --------------------
503 // --------------------------------------------------------------
504
505 wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
506 {
507 wxSockCbk old_cbk = cbk_;
508
509 m_cbk = cbk_;
510 return old_cbk;
511 }
512
513 char *wxSocketBase::CallbackData(char *data)
514 {
515 char *old_data = m_cdata;
516
517 m_cdata = data;
518 return old_data;
519 }
520
521 // --------------------------------------------------------------
522 // --------- wxSocketBase wait functions ------------------------
523 // --------------------------------------------------------------
524
525 class _wxSocketInternalTimer: public wxTimer {
526 public:
527 int *m_state;
528
529 void Notify()
530 {
531 *m_state = GSOCK_MAX_EVENT; // Just to say it's a timeout.
532 }
533 };
534
535 static void wx_socket_wait(GSocket *socket, GSocketEvent event, char *cdata)
536 {
537 int *state = (int *)cdata;
538
539 *state = event;
540 }
541
542 bool wxSocketBase::_Wait(long seconds, long milliseconds, int type)
543 {
544 bool old_notify_state = m_notify_state;
545 int state = 0;
546 _wxSocketInternalTimer timer;
547
548 if (!m_connected || !m_socket)
549 return FALSE;
550
551 timer.m_state = &state;
552
553 Notify(FALSE);
554
555 timer.Start(seconds * 1000 + milliseconds, TRUE);
556 GSocket_SetFallback(m_socket, type, wx_socket_wait, (char *)&state);
557
558 while (state == 0)
559 wxYield();
560
561 GSocket_UnsetFallback(m_socket, type);
562 timer.Stop();
563
564 Notify(old_notify_state);
565
566 return (state != GSOCK_MAX_EVENT);
567 }
568
569 bool wxSocketBase::Wait(long seconds, long milliseconds)
570 {
571 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
572 GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
573 }
574
575 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
576 {
577 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
578 }
579
580 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
581 {
582 return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
583 }
584
585 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
586 {
587 return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
588 }
589
590 // --------------------------------------------------------------
591 // --------- wxSocketBase callback management -------------------
592 // --------------------------------------------------------------
593
594 GSocketEventFlags wxSocketBase::EventToNotify(GSocketEvent evt)
595 {
596 switch (evt)
597 {
598 case GSOCK_INPUT:
599 return GSOCK_INPUT_FLAG;
600 case GSOCK_OUTPUT:
601 return GSOCK_OUTPUT_FLAG;
602 case GSOCK_CONNECTION:
603 return GSOCK_CONNECTION_FLAG;
604 case GSOCK_LOST:
605 return GSOCK_LOST_FLAG;
606 default:
607 return 0;
608 }
609 return 0;
610 }
611
612 void wxSocketBase::SetFlags(wxSockFlags _flags)
613 {
614 m_flags = _flags;
615 }
616
617 wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const
618 {
619 return m_flags;
620 }
621
622 void wxSocketBase::SetNotify(GSocketEventFlags flags)
623 {
624 /* Check if server */
625 if (m_type != SOCK_SERVER)
626 flags &= ~GSOCK_CONNECTION_FLAG;
627
628 m_neededreq = flags;
629 if (m_neededreq == 0)
630 Notify(FALSE);
631 else
632 Notify(m_notify_state);
633 }
634
635 // --------------------------------------------------------------
636 // Automatic notifier
637 // --------------------------------------------------------------
638
639 static void wx_socket_fallback(GSocket *socket, GSocketEvent event, char *cdata)
640 {
641 wxSocketBase *sckobj = (wxSocketBase *)cdata;
642
643 sckobj->OnRequest(event);
644 }
645
646 void wxSocketBase::Notify(bool notify)
647 {
648 m_notify_state = notify;
649 if (!m_socket)
650 return;
651
652 GSocket_UnsetFallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
653 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
654 if (!notify)
655 return;
656
657 GSocket_SetFallback(m_socket, m_neededreq, wx_socket_fallback, (char *)this);
658 }
659
660 void wxSocketBase::OnRequest(GSocketEvent req_evt)
661 {
662 wxSocketEvent event(m_id);
663 GSocketEventFlags notify = EventToNotify(req_evt);
664
665 if (m_defering != NO_DEFER) {
666 DoDefer(req_evt);
667 return;
668 }
669
670 if ((m_neededreq & notify) == notify) {
671 event.m_socket = this;
672 event.m_skevt = req_evt;
673 ProcessEvent(event);
674 OldOnNotify(req_evt);
675 }
676
677 if (req_evt == GSOCK_LOST)
678 Close();
679 }
680
681 void wxSocketBase::OldOnNotify(GSocketEvent evt)
682 {
683 }
684
685 // --------------------------------------------------------------
686 // --------- wxSocketBase functions [Callback, CallbackData] ----
687 // --------------------------------------------------------------
688
689 void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
690 {
691 SetNextHandler(&h_evt);
692 m_id = id;
693 }
694
695 // --------------------------------------------------------------
696 // --------- wxSocketBase pushback library ----------------------
697 // --------------------------------------------------------------
698
699 void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
700 {
701 char *curr_pos;
702
703 if (m_unread != NULL)
704 m_unread = (char *) realloc(m_unread, m_unrd_size+size);
705 else
706 m_unread = (char *) malloc(size);
707
708 curr_pos = m_unread + m_unrd_size;
709
710 memcpy(curr_pos, buffer, size);
711 m_unrd_size += size;
712 }
713
714 void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
715 {
716 if (m_unread == NULL)
717 m_unread = (char *)malloc(size);
718 else {
719 char *tmp;
720
721 tmp = (char *)malloc(m_unrd_size + size);
722 memcpy(tmp+size, m_unread, m_unrd_size);
723 free(m_unread);
724
725 m_unread = tmp;
726 }
727
728 m_unrd_size += size;
729
730 memcpy(m_unread, buffer, size);
731 }
732
733 size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
734 {
735 if (!m_unrd_size)
736 return 0;
737
738 if (size > (m_unrd_size-m_unrd_cur))
739 size = m_unrd_size-m_unrd_cur;
740 memcpy(buffer, (m_unread+m_unrd_cur), size);
741
742 if (!peek) {
743 m_unrd_cur += size;
744 if (m_unrd_size == m_unrd_cur) {
745 free(m_unread);
746 m_unread = NULL;
747 m_unrd_size = 0;
748 m_unrd_cur = 0;
749 }
750 }
751
752 return size;
753 }
754
755 // --------------------------------------------------------------
756 // wxSocketServer
757 // --------------------------------------------------------------
758
759 wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
760 wxSockFlags flags) :
761 wxSocketBase(flags, SOCK_SERVER)
762 {
763 m_socket = GSocket_new();
764
765 if (!m_socket)
766 return;
767
768 GSocket_SetLocal(m_socket, addr_man.GetAddress());
769 if (GSocket_SetServer(m_socket) != GSOCK_NOERROR) {
770 GSocket_destroy(m_socket);
771 m_socket = NULL;
772 return;
773 }
774
775 Notify(TRUE);
776 }
777
778 // --------------------------------------------------------------
779 // wxSocketServer Accept
780 // --------------------------------------------------------------
781
782 bool wxSocketServer::AcceptWith(wxSocketBase& sock)
783 {
784 GSocket *child_socket;
785
786 child_socket = GSocket_WaitConnection(m_socket);
787
788 sock.m_type = SOCK_INTERNAL;
789 sock.m_socket = child_socket;
790 sock.m_connected = TRUE;
791
792 return TRUE;
793 }
794
795 wxSocketBase *wxSocketServer::Accept()
796 {
797 wxSocketBase* sock = new wxSocketBase();
798
799 sock->SetFlags((wxSockFlags)m_flags);
800
801 if (!AcceptWith(*sock))
802 return NULL;
803
804 return sock;
805 }
806
807 // --------------------------------------------------------------
808 // wxSocketClient
809 // --------------------------------------------------------------
810
811 // --------- wxSocketClient CONSTRUCTOR -------------------------
812 // --------------------------------------------------------------
813 wxSocketClient::wxSocketClient(wxSockFlags _flags) :
814 wxSocketBase(_flags, SOCK_CLIENT)
815 {
816 }
817
818 // --------------------------------------------------------------
819 // --------- wxSocketClient DESTRUCTOR --------------------------
820 // --------------------------------------------------------------
821 wxSocketClient::~wxSocketClient()
822 {
823 }
824
825 // --------------------------------------------------------------
826 // --------- wxSocketClient Connect functions -------------------
827 // --------------------------------------------------------------
828 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
829 {
830 if (IsConnected())
831 Close();
832
833 // This should never happen.
834 if (m_socket)
835 GSocket_destroy(m_socket);
836
837 // Initializes all socket stuff ...
838 // --------------------------------
839 m_socket = GSocket_new();
840
841 if (!m_socket)
842 return FALSE;
843
844 m_connected = FALSE;
845
846 // Update the flags of m_socket.
847 SetFlags(m_flags);
848 GSocket_SetPeer(m_socket, addr_man.GetAddress());
849 if (GSocket_Connect(m_socket, GSOCK_STREAMED) != GSOCK_NOERROR)
850 return FALSE;
851
852 // Enables bg events.
853 // ------------------
854 Notify(TRUE);
855
856 m_connected = TRUE;
857 return TRUE;
858 }
859
860 bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
861 {
862 int ret = _Wait(seconds, microseconds, GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
863
864 if (ret)
865 m_connected = TRUE;
866
867 return m_connected;
868 }
869
870 void wxSocketClient::OnRequest(GSocketEvent evt)
871 {
872 if (evt == GSOCK_CONNECTION)
873 {
874 if (m_connected)
875 {
876 m_neededreq &= ~GSOCK_CONNECTION_FLAG;
877 return;
878 }
879 m_connected = TRUE;
880 return;
881 }
882 wxSocketBase::OnRequest(evt);
883 }
884
885 // --------------------------------------------------------------
886 // wxSocketEvent
887 // --------------------------------------------------------------
888
889 wxSocketEvent::wxSocketEvent(int id)
890 : wxEvent(id)
891 {
892 wxEventType type = (wxEventType)wxEVT_SOCKET;
893
894 SetEventType(type);
895 }
896
897 void wxSocketEvent::CopyObject(wxObject& obj_d) const
898 {
899 wxSocketEvent *event = (wxSocketEvent *)&obj_d;
900
901 wxEvent::CopyObject(obj_d);
902
903 event->m_skevt = m_skevt;
904 event->m_socket = m_socket;
905 }
906
907 // --------------------------------------------------------------------------
908 // wxSocketModule
909 // --------------------------------------------------------------------------
910 class WXDLLEXPORT wxSocketModule: public wxModule {
911 DECLARE_DYNAMIC_CLASS(wxSocketModule)
912 public:
913 bool OnInit() {
914 return GSocket_Init();
915 }
916 void OnExit() {
917 GSocket_Cleanup();
918 }
919 };
920
921 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
922
923 #endif
924 // wxUSE_SOCKETS