]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
5f23f76f9cf4df5555613015a65e2f0a09ec2c81
[wxWidgets.git] / src / common / socket.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: socket.cpp
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
5 // Created: April 1997
6 // Updated: September 1999
7 // Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
8 // (C) 1999, Guillermo Rodriguez Garcia
9 // RCS_ID: $Id$
10 // License: see wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
12
13 #ifdef __GNUG__
14 #pragma implementation "socket.h"
15 #endif
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 /////////////////////////////////////////////////////////////////////////////
27 // wxWindows headers
28 /////////////////////////////////////////////////////////////////////////////
29 #include "wx/defs.h"
30 #include "wx/object.h"
31 #include "wx/string.h"
32 #include "wx/timer.h"
33 #include "wx/utils.h"
34 #include "wx/module.h"
35 #include "wx/log.h"
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40
41 /////////////////////////////////////////////////////////////////////////////
42 // wxSocket headers
43 /////////////////////////////////////////////////////////////////////////////
44 #include "wx/sckaddr.h"
45 #include "wx/socket.h"
46
47
48 #if defined(__WXMSW__) || defined(__WXPM__)
49 #define PROCESS_EVENTS() wxYield()
50 #elif defined(__WXGTK__)
51 #include <gtk/gtk.h>
52 #define PROCESS_EVENTS() gtk_main_iteration()
53 #endif
54
55
56 // --------------------------------------------------------------
57 // ClassInfos
58 // --------------------------------------------------------------
59 #if !USE_SHARED_LIBRARY
60 IMPLEMENT_CLASS(wxSocketBase, wxObject)
61 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
62 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
63 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
64 #endif
65
66 class wxSocketState : public wxObject
67 {
68 public:
69 bool notify_state;
70 GSocketEventFlags evt_notify_state;
71 wxSocketBase::wxSockFlags socket_flags;
72 wxSocketBase::wxSockCbk c_callback;
73 char *c_callback_data;
74
75 public:
76 wxSocketState() : wxObject() {}
77 };
78
79 // --------------------------------------------------------------
80 // wxSocketBase ctor and dtor
81 // --------------------------------------------------------------
82
83 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
84 wxSocketBase::wxSockType _type) :
85 wxEvtHandler(),
86 m_socket(NULL), m_id(-1),
87 m_flags(_flags), m_type(_type),
88 m_neededreq(0), m_notify_state(FALSE),
89 m_connected(FALSE), m_establishing(FALSE),
90 m_reading(FALSE), m_writing(FALSE),
91 m_error(FALSE), m_lcount(0), m_timeout(600), m_states(),
92 m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
93 m_defering(NO_DEFER), m_defer_buffer(NULL), m_defer_timer(NULL),
94 m_cbk(NULL), m_cdata(NULL)
95 {
96 }
97
98 wxSocketBase::wxSocketBase() :
99 wxEvtHandler(),
100 m_socket(NULL), m_id(-1),
101 m_flags(NONE), m_type(SOCK_UNINIT),
102 m_neededreq(0), m_notify_state(FALSE),
103 m_connected(FALSE), m_establishing(FALSE),
104 m_reading(FALSE), m_writing(FALSE),
105 m_error(FALSE), m_lcount(0), m_timeout(600), m_states(),
106 m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
107 m_defering(NO_DEFER), m_defer_buffer(NULL), m_defer_timer(NULL),
108 m_cbk(NULL), m_cdata(NULL)
109 {
110 }
111
112 wxSocketBase::~wxSocketBase()
113 {
114 if (m_unread)
115 free(m_unread);
116
117 // Shutdown and close the socket
118 Close();
119
120 // Destroy the GSocket object
121 if (m_socket)
122 GSocket_destroy(m_socket);
123 }
124
125 bool wxSocketBase::Close()
126 {
127 if (m_socket)
128 {
129 // Disable callbacks
130 GSocket_UnsetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
131 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
132
133 // Shutdown the connection
134 GSocket_Shutdown(m_socket);
135 m_connected = FALSE;
136 m_establishing = FALSE;
137 }
138
139 return TRUE;
140 }
141
142 // --------------------------------------------------------------
143 // wxSocketBase basic IO operations
144 // --------------------------------------------------------------
145
146 // All IO operations {Read, Write, ReadMsg, WriteMsg, Peek,
147 // Unread, Discard} update m_error and m_lcount.
148 //
149 // TODO: Should Connect, Accept and AcceptWith update m_error?
150
151 class _wxSocketInternalTimer: public wxTimer
152 {
153 public:
154 int *m_state;
155 unsigned long m_new_val;
156
157 void Notify()
158 {
159 *m_state = m_new_val; // Change the value
160 }
161 };
162
163 wxUint32 wxSocketBase::DeferRead(char *buffer, wxUint32 nbytes)
164 {
165 // Timer for timeout
166 _wxSocketInternalTimer timer;
167
168 //wxLogMessage("Entrando a DeferRead, nbytes = %d", nbytes);
169 wxASSERT(m_defering == NO_DEFER);
170
171 // Set the defering mode to READ.
172 m_defering = DEFER_READ;
173
174 // Set the current buffer.
175 m_defer_buffer = buffer;
176 m_defer_nbytes = nbytes;
177 m_defer_timer = &timer;
178
179 timer.m_state = (int *)&m_defer_buffer;
180 timer.m_new_val = 0;
181
182 timer.Start(m_timeout * 1000, FALSE);
183
184 // If the socket is readable, call DoDefer for the first time
185 if (GSocket_Select(m_socket, GSOCK_INPUT_FLAG))
186 {
187 //wxLogMessage("Llamando al primer DoDefer");
188 DoDefer();
189 }
190
191 // Wait for buffer completion.
192 while (m_defer_buffer != NULL)
193 PROCESS_EVENTS();
194
195 timer.Stop();
196
197 // Disable defering mode.
198 m_defering = NO_DEFER;
199 m_defer_timer = NULL;
200
201 // Return the number of bytes read from the socket.
202 //wxLogMessage("Saliendo de DeferRead: total: %d bytes", nbytes - m_defer_nbytes);
203 return nbytes-m_defer_nbytes;
204 }
205
206 wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes)
207 {
208 // Mask read events
209 m_reading = TRUE;
210
211 m_lcount = _Read(buffer, nbytes);
212
213 // If in WAITALL mode, all bytes should have been read.
214 if (m_flags & WAITALL)
215 m_error = (m_lcount != nbytes);
216 else
217 m_error = (m_lcount == 0);
218
219 // Trigger another read event if there is still data available.
220 m_reading = FALSE;
221 // TODO: TriggerRead
222
223 return *this;
224 }
225
226 wxUint32 wxSocketBase::_Read(char* buffer, wxUint32 nbytes)
227 {
228 int total;
229 int ret = 1;
230
231 // we try this even if the connection has already been closed.
232 total = GetPushback(buffer, nbytes, FALSE);
233 nbytes -= total;
234 buffer += total;
235
236 // If the socket is not connected, or we have got the whole
237 // needed buffer, return immedately
238 if (!m_connected || !m_socket || !nbytes)
239 return total;
240
241 // Possible combinations (they are checked in this order)
242 // NOWAIT
243 // SPEED | WAITALL
244 // SPEED
245 // WAITALL
246 // NONE
247 //
248 if (m_flags & NOWAIT) // NOWAIT
249 {
250 GSocket_SetNonBlocking(m_socket, TRUE);
251 ret = GSocket_Read(m_socket, buffer, nbytes);
252 GSocket_SetNonBlocking(m_socket, FALSE);
253
254 if (ret > 0)
255 total += ret;
256 }
257 else if ((m_flags & SPEED) && (m_flags & WAITALL)) // SPEED, WAITALL
258 {
259 while (ret > 0 && nbytes > 0)
260 {
261 ret = GSocket_Read(m_socket, buffer, nbytes);
262 total += ret;
263 buffer += ret;
264 nbytes -= ret;
265 }
266 // In case the last call was an error ...
267 if (ret < 0)
268 total++;
269 }
270 else if (m_flags & SPEED) // SPEED, !WAITALL
271 {
272 ret = GSocket_Read(m_socket, buffer, nbytes);
273
274 if (ret > 0)
275 total += ret;
276 }
277 else // NONE or WAITALL
278 {
279 ret = DeferRead(buffer, nbytes);
280
281 if (ret > 0)
282 total += ret;
283 }
284
285 return total;
286 }
287
288 wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 nbytes)
289 {
290 #define MAX_DISCARD_SIZE (10 * 1024)
291
292 wxUint32 len, len2, sig, total;
293 bool error;
294 int old_flags;
295 struct
296 {
297 unsigned char sig[4];
298 unsigned char len[4];
299 } msg;
300
301 // Mask read events
302 m_reading = TRUE;
303
304 total = 0;
305 error = TRUE;
306 old_flags = m_flags;
307 SetFlags((m_flags & SPEED) | WAITALL);
308
309 if (_Read((char *)&msg, sizeof(msg)) != sizeof(msg))
310 goto exit;
311
312 sig = (wxUint32)msg.sig[0];
313 sig |= (wxUint32)(msg.sig[1] << 8);
314 sig |= (wxUint32)(msg.sig[2] << 16);
315 sig |= (wxUint32)(msg.sig[3] << 24);
316
317 if (sig != 0xfeeddead)
318 {
319 wxLogMessage(T("Warning: invalid signature returned to ReadMsg"));
320 goto exit;
321 }
322
323 len = (wxUint32)msg.len[0];
324 len |= (wxUint32)(msg.len[1] << 8);
325 len |= (wxUint32)(msg.len[2] << 16);
326 len |= (wxUint32)(msg.len[3] << 24);
327
328 //wxLogMessage("Readmsg: %d %d %d %d -> len == %d",
329 // msg.len[0], msg.len[1], msg.len[2], msg.len[3], len);
330
331 if (len > nbytes)
332 {
333 len2 = len - nbytes;
334 len = nbytes;
335 }
336 else
337 len2 = 0;
338
339 // This check is necessary so that we don't attemp to read if
340 // the msg was zero bytes long.
341 if (len)
342 {
343 total = _Read(buffer, len);
344
345 if (total != len)
346 goto exit;
347 }
348 if (len2)
349 {
350 char *discard_buffer = new char[MAX_DISCARD_SIZE];
351 long discard_len;
352
353 // NOTE: discarded bytes don't add to m_lcount.
354 do
355 {
356 discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
357 discard_len = _Read(discard_buffer, discard_len);
358 len2 -= discard_len;
359 }
360 while ((discard_len > 0) && len2);
361
362 delete [] discard_buffer;
363
364 if (len2 != 0)
365 goto exit;
366 }
367 if (_Read((char *)&msg, sizeof(msg)) != sizeof(msg))
368 goto exit;
369
370 sig = (wxUint32)msg.sig[0];
371 sig |= (wxUint32)(msg.sig[1] << 8);
372 sig |= (wxUint32)(msg.sig[2] << 16);
373 sig |= (wxUint32)(msg.sig[3] << 24);
374
375 if (sig != 0xdeadfeed)
376 {
377 //wxLogMessage(T("Warning: invalid signature returned to ReadMsg"));
378 goto exit;
379 }
380
381 // everything was OK
382 error = FALSE;
383
384 exit:
385 m_error = error;
386 m_lcount = total;
387 m_reading = FALSE;
388 SetFlags(old_flags);
389
390 // TODO: TriggerRead
391 return *this;
392
393 #undef MAX_DISCARD_SIZE
394 }
395
396 wxSocketBase& wxSocketBase::Peek(char* buffer, wxUint32 nbytes)
397 {
398 // Mask read events
399 m_reading = TRUE;
400
401 m_lcount = _Read(buffer, nbytes);
402 Pushback(buffer, nbytes);
403
404 // If in WAITALL mode, all bytes should have been read.
405 if (m_flags & WAITALL)
406 m_error = (m_lcount != nbytes);
407 else
408 m_error = (m_lcount == 0);
409
410 // Trigger another read event if there is still data available.
411 m_reading = FALSE;
412
413 // TODO: TriggerRead
414 return *this;
415 }
416
417 wxUint32 wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes)
418 {
419 // Timer for timeout
420 _wxSocketInternalTimer timer;
421
422 wxASSERT(m_defering == NO_DEFER);
423 //wxLogMessage("Entrando a DeferWrite");
424
425 m_defering = DEFER_WRITE;
426
427 // Set the current buffer
428 m_defer_buffer = (char *)buffer;
429 m_defer_nbytes = nbytes;
430 m_defer_timer = &timer;
431
432 // Start timer
433 timer.m_state = (int *)&m_defer_buffer;
434 timer.m_new_val = 0;
435
436 timer.Start(m_timeout * 1000, FALSE);
437
438 // If the socket is writable, call DoDefer for the first time
439 if (GSocket_Select(m_socket, GSOCK_OUTPUT_FLAG))
440 {
441 //wxLogMessage("Llamando al primer DoDefer");
442 DoDefer();
443 }
444
445 // Wait for buffer completion.
446 while (m_defer_buffer != NULL)
447 PROCESS_EVENTS();
448
449 timer.Stop();
450
451 // Disable defering mode
452 m_defer_timer = NULL;
453 m_defering = NO_DEFER;
454
455 wxString s;
456 s.Printf("Saliendo de DeferWrite: total %d bytes", nbytes-m_defer_nbytes);
457 //wxLogMessage(s);
458
459 return nbytes-m_defer_nbytes;
460 }
461
462 wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
463 {
464 // Mask write events
465 m_writing = TRUE;
466
467 m_lcount = _Write(buffer, nbytes);
468
469 // If in WAITALL mode, all bytes should have been written.
470 if (m_flags & WAITALL)
471 m_error = (m_lcount != nbytes);
472 else
473 m_error = (m_lcount == 0);
474
475 // Trigger another write event if the socket is still writable
476 m_writing = FALSE;
477
478 // TODO: TriggerWrite
479 return *this;
480 }
481
482 wxUint32 wxSocketBase::_Write(const char *buffer, wxUint32 nbytes)
483 {
484 wxUint32 total = 0;
485 int ret = 1;
486
487 if (!m_connected || !m_socket)
488 return 0;
489
490 // Possible combinations (they are checked in this order)
491 // NOWAIT
492 // SPEED | WAITALL
493 // SPEED
494 // WAITALL
495 // NONE
496 //
497 if (m_flags & NOWAIT) // NOWAIT
498 {
499 GSocket_SetNonBlocking(m_socket, TRUE);
500 ret = GSocket_Write(m_socket, buffer, nbytes);
501 GSocket_SetNonBlocking(m_socket, FALSE);
502
503 if (ret > 0)
504 total = ret;
505 }
506 else if ((m_flags & SPEED) && (m_flags & WAITALL)) // SPEED, WAITALL
507 {
508 while (ret > 0 && nbytes > 0)
509 {
510 ret = GSocket_Write(m_socket, buffer, nbytes);
511 total += ret;
512 buffer += ret;
513 nbytes -= ret;
514 }
515 // In case the last call was an error ...
516 if (ret < 0)
517 total ++;
518 }
519 else if (m_flags & SPEED) // SPEED, !WAITALL
520 {
521 ret = GSocket_Write(m_socket, buffer, nbytes);
522
523 if (ret > 0)
524 total = ret;
525 }
526 else // NONE or WAITALL
527 {
528 ret = DeferWrite(buffer, nbytes);
529
530 if (ret > 0)
531 total = ret;
532 }
533
534 return total;
535 }
536
537 wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 nbytes)
538 {
539 wxUint32 total;
540 bool error;
541 int old_flags;
542 struct {
543 unsigned char sig[4];
544 unsigned char len[4];
545 } msg;
546
547 // Mask write events
548 m_writing = TRUE;
549
550 error = TRUE;
551 total = 0;
552 old_flags = m_flags;
553 SetFlags((m_flags & SPEED) | WAITALL);
554
555 // warning about 'cast truncates constant value'
556 #ifdef __VISUALC__
557 # pragma warning(disable: 4310)
558 #endif // __VISUALC__
559
560 msg.sig[0] = (unsigned char) 0xad;
561 msg.sig[1] = (unsigned char) 0xde;
562 msg.sig[2] = (unsigned char) 0xed;
563 msg.sig[3] = (unsigned char) 0xfe;
564
565 msg.len[0] = (unsigned char) nbytes & 0xff;
566 msg.len[1] = (unsigned char) (nbytes >> 8) & 0xff;
567 msg.len[2] = (unsigned char) (nbytes >> 16) & 0xff;
568 msg.len[3] = (unsigned char) (nbytes >> 24) & 0xff;
569
570 //wxLogMessage("Writemsg: %d %d %d %d -> %d",
571 // nbytes & 0xff,
572 // (nbytes >> 8) & 0xff,
573 // (nbytes >> 16) & 0xff,
574 // (nbytes >> 24) & 0xff,
575 // nbytes
576 // );
577
578 if (_Write((char *)&msg, sizeof(msg)) < sizeof(msg))
579 goto exit;
580
581 total = _Write(buffer, nbytes);
582
583 if (total < nbytes)
584 goto exit;
585
586 msg.sig[0] = (unsigned char) 0xed;
587 msg.sig[1] = (unsigned char) 0xfe;
588 msg.sig[2] = (unsigned char) 0xad;
589 msg.sig[3] = (unsigned char) 0xde;
590 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
591
592 if ((_Write((char *)&msg, sizeof(msg))) < sizeof(msg))
593 goto exit;
594
595 // everything was OK
596 error = FALSE;
597
598 exit:
599 m_error = error;
600 m_lcount = total;
601 m_writing = FALSE;
602
603 // TODO: TriggerWrite
604 return *this;
605
606 #ifdef __VISUALC__
607 # pragma warning(default: 4310)
608 #endif // __VISUALC__
609 }
610
611 wxSocketBase& wxSocketBase::Unread(const char *buffer, wxUint32 nbytes)
612 {
613 if (nbytes != 0)
614 Pushback(buffer, nbytes);
615
616 m_error = FALSE;
617 m_lcount = nbytes;
618
619 return *this;
620 }
621
622 void wxSocketBase::DoDefer()
623 {
624 int ret;
625
626 if (!m_defer_buffer)
627 return;
628
629 switch(m_defering)
630 {
631 case DEFER_READ:
632 ret = GSocket_Read(m_socket, m_defer_buffer, m_defer_nbytes);
633 break;
634 case DEFER_WRITE:
635 ret = GSocket_Write(m_socket, m_defer_buffer, m_defer_nbytes);
636 break;
637 default:
638 ret = -1;
639 }
640
641 if (ret >= 0)
642 m_defer_nbytes -= ret;
643
644 // If we are waiting for all bytes to be acquired, keep the defering
645 // mode enabled.
646 if (!(m_flags & WAITALL) || !m_defer_nbytes || ret < 0)
647 {
648 m_defer_buffer = NULL;
649 }
650 else
651 {
652 m_defer_buffer += ret;
653 m_defer_timer->Start(m_timeout * 1000, FALSE);
654 }
655
656 //wxLogMessage("DoDefer ha transferido %d bytes", ret);
657 }
658
659 wxSocketBase& wxSocketBase::Discard()
660 {
661 #define MAX_BUFSIZE (10*1024)
662
663 int old_flags;
664 char *my_data = new char[MAX_BUFSIZE];
665 wxUint32 recv_size = MAX_BUFSIZE;
666 wxUint32 total = 0;
667
668 // Mask read events
669 m_reading = TRUE;
670
671 old_flags = m_flags;
672 SetFlags(NOWAIT);
673
674 while (recv_size == MAX_BUFSIZE)
675 {
676 recv_size = _Read(my_data, MAX_BUFSIZE);
677 total += recv_size;
678 }
679
680 delete [] my_data;
681 m_lcount = total;
682 m_error = FALSE;
683
684 // Trigger another read event if there is still data available.
685 m_reading = FALSE;
686
687 // TODO: TriggerRead
688 return *this;
689
690 #undef MAX_BUFSIZE
691 }
692
693 // --------------------------------------------------------------
694 // wxSocketBase get local or peer addresses
695 // --------------------------------------------------------------
696
697 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
698 {
699 GAddress *peer;
700
701 if (!m_socket)
702 return FALSE;
703
704 peer = GSocket_GetPeer(m_socket);
705 addr_man.SetAddress(peer);
706 GAddress_destroy(peer);
707
708 return TRUE;
709 }
710
711 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
712 {
713 GAddress *local;
714
715 if (!m_socket)
716 return FALSE;
717
718 local = GSocket_GetLocal(m_socket);
719 addr_man.SetAddress(local);
720 GAddress_destroy(local);
721
722 return TRUE;
723 }
724
725 // --------------------------------------------------------------
726 // wxSocketBase save and restore socket state
727 // --------------------------------------------------------------
728
729 void wxSocketBase::SaveState()
730 {
731 wxSocketState *state;
732
733 state = new wxSocketState();
734
735 state->notify_state = m_notify_state;
736 state->evt_notify_state = m_neededreq;
737 state->socket_flags = m_flags;
738 state->c_callback = m_cbk;
739 state->c_callback_data = m_cdata;
740
741 m_states.Append(state);
742 }
743
744 void wxSocketBase::RestoreState()
745 {
746 wxNode *node;
747 wxSocketState *state;
748
749 node = m_states.Last();
750 if (!node)
751 return;
752
753 state = (wxSocketState *)node->Data();
754
755 SetFlags(state->socket_flags);
756 m_neededreq = state->evt_notify_state;
757 m_cbk = state->c_callback;
758 m_cdata = state->c_callback_data;
759 Notify(state->notify_state);
760
761 delete node;
762 delete state;
763 }
764
765
766 // --------------------------------------------------------------
767 // wxSocketBase Wait functions
768 // --------------------------------------------------------------
769
770 // GRG: I have completely rewritten this family of functions
771 // so that they don't depend on event notifications; instead,
772 // they poll the socket, using GSocket_Select(), to check for
773 // the specified combination of event flags, until an event
774 // occurs or until the timeout ellapses. The polling loop
775 // calls PROCESS_EVENTS(), so this won't block the GUI.
776
777 bool wxSocketBase::_Wait(long seconds, long milliseconds, wxSocketEventFlags flags)
778 {
779 GSocketEventFlags result;
780 _wxSocketInternalTimer timer;
781 long timeout;
782 int state = -1;
783
784 // Check for valid socket
785 if (!m_socket)
786 return FALSE;
787
788 // If it is not a server, it must be connected or establishing connection
789 if ((m_type != SOCK_SERVER) && (!m_connected && !m_establishing))
790 return FALSE;
791
792 // Check for valid timeout value
793 if (seconds != -1)
794 timeout = seconds * 1000 + milliseconds;
795 else
796 timeout = m_timeout * 1000;
797
798 // Activate timer
799 if (timeout)
800 {
801 timer.m_state = &state;
802 timer.m_new_val = 0;
803 timer.Start(timeout, TRUE);
804 }
805
806 // Active polling (without using events)
807 //
808 // NOTE: this duplicates some of the code in OnRequest (lost
809 // connection and connection establishment handling) but this
810 // doesn't hurt. It has to be here because the event might
811 // be a bit delayed, and it has to be in OnRequest as well
812 // because maybe the WaitXXX functions are not being used.
813 //
814 // Do this at least once (important if timeout == 0, when
815 // we are just polling)
816 do
817 {
818 result = GSocket_Select(m_socket, flags | GSOCK_LOST_FLAG);
819
820 // Connection lost
821 if (result & GSOCK_LOST_FLAG)
822 {
823 timer.Stop();
824 m_defer_buffer = NULL;
825 Close();
826 return TRUE;
827 }
828
829 // Incoming connection (server) or connection established (client)
830 if (result & GSOCK_CONNECTION_FLAG)
831 {
832 timer.Stop();
833 m_connected = TRUE;
834 m_establishing = FALSE;
835 return TRUE;
836 }
837
838 // If we are in the middle of a R/W operation, do not propagate
839 // to users.
840 if ( ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
841 && (!m_writing) && (!m_reading) )
842 {
843 /* TODO: remove this
844 if (m_defer_buffer == NULL)
845 */
846 {
847 timer.Stop();
848 return TRUE;
849 }
850 }
851
852 if (timeout != 0)
853 PROCESS_EVENTS();
854 }
855 while ((state == -1) && timeout);
856
857 timer.Stop();
858 return FALSE;
859 }
860
861 bool wxSocketBase::Wait(long seconds, long milliseconds)
862 {
863 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
864 GSOCK_OUTPUT_FLAG |
865 GSOCK_CONNECTION_FLAG |
866 GSOCK_LOST_FLAG);
867 }
868
869 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
870 {
871 // Check pushback buffer
872 if (m_unread)
873 return TRUE;
874
875 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG);
876 }
877
878 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
879 {
880 return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
881 }
882
883 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
884 {
885 return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
886 }
887
888 void wxSocketBase::SetTimeout(long seconds)
889 {
890 m_timeout = seconds;
891
892 if (m_socket)
893 GSocket_SetTimeout(m_socket, m_timeout);
894 }
895
896 // --------------------------------------------------------------
897 // wxSocketBase flags
898 // --------------------------------------------------------------
899
900 void wxSocketBase::SetFlags(wxSockFlags _flags)
901 {
902 m_flags = _flags;
903 }
904
905 // --------------------------------------------------------------
906 // wxSocketBase callback management
907 // --------------------------------------------------------------
908
909 wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSockCbk cbk_)
910 {
911 wxSockCbk old_cbk = cbk_;
912
913 m_cbk = cbk_;
914 return old_cbk;
915 }
916
917 char *wxSocketBase::CallbackData(char *data)
918 {
919 char *old_data = m_cdata;
920
921 m_cdata = data;
922 return old_data;
923 }
924
925 // --------------------------------------------------------------
926 // wxSocketBase automatic notifier
927 // --------------------------------------------------------------
928
929 // All events (INPUT, OUTPUT, CONNECTION, LOST) are now always
930 // internally watched; but users will only be notified of those
931 // events they are interested in.
932
933 static void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket),
934 GSocketEvent event, char *cdata)
935 {
936 wxSocketBase *sckobj = (wxSocketBase *)cdata;
937
938 sckobj->OnRequest((wxSocketNotify)event);
939 }
940
941 wxSocketEventFlags wxSocketBase::EventToNotify(wxSocketNotify evt)
942 {
943 switch (evt)
944 {
945 case GSOCK_INPUT: return GSOCK_INPUT_FLAG;
946 case GSOCK_OUTPUT: return GSOCK_OUTPUT_FLAG;
947 case GSOCK_CONNECTION: return GSOCK_CONNECTION_FLAG;
948 case GSOCK_LOST: return GSOCK_LOST_FLAG;
949 }
950 return 0;
951 }
952
953 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
954 {
955 m_neededreq = flags;
956 }
957
958 void wxSocketBase::Notify(bool notify)
959 {
960 m_notify_state = notify;
961 }
962
963 void wxSocketBase::OnRequest(wxSocketNotify req_evt)
964 {
965 wxSocketEvent event(m_id);
966 wxSocketEventFlags flag = EventToNotify(req_evt);
967
968 // fprintf(stderr, "%s: Entering OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
969
970 // NOTE: this duplicates some of the code in _Wait (lost
971 // connection and connection establishment handling) but
972 // this doesn't hurt. It has to be here because maybe the
973 // WaitXXX are not being used, and it has to be in _Wait
974 // as well because the event might be a bit delayed.
975 //
976 switch(req_evt)
977 {
978 case wxSOCKET_CONNECTION:
979 m_establishing = FALSE;
980 m_connected = TRUE;
981 break;
982 case wxSOCKET_LOST:
983 m_defer_buffer = NULL;
984 Close();
985 break;
986 case wxSOCKET_INPUT:
987 case wxSOCKET_OUTPUT:
988 if (m_defer_buffer)
989 {
990 // fprintf(stderr, "%s: Habia buffer, evt %d skipped\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
991 DoDefer();
992 // Do not notify to user
993 return;
994 }
995 break;
996 }
997
998 // If we are in the middle of a R/W operation, do not
999 // propagate events to users.
1000 if (((req_evt == wxSOCKET_INPUT) && m_reading) ||
1001 ((req_evt == wxSOCKET_OUTPUT) && m_writing))
1002 {
1003 // fprintf(stderr, "%s: Swallowed evt %d\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
1004 return;
1005 }
1006
1007 if (((m_neededreq & flag) == flag) && m_notify_state)
1008 {
1009 // fprintf(stderr, "%s: Evt %d delivered\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
1010 event.m_socket = this;
1011 event.m_skevt = req_evt;
1012 ProcessEvent(event);
1013 OldOnNotify(req_evt);
1014
1015 if (m_cbk)
1016 m_cbk(*this, req_evt, m_cdata);
1017 }
1018
1019 // fprintf(stderr, "%s: Exiting OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
1020 }
1021
1022 void wxSocketBase::OldOnNotify(wxSocketNotify WXUNUSED(evt))
1023 {
1024 }
1025
1026 // --------------------------------------------------------------
1027 // wxSocketBase set event handler
1028 // --------------------------------------------------------------
1029
1030 void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
1031 {
1032 SetNextHandler(&h_evt);
1033 m_id = id;
1034 }
1035
1036 // --------------------------------------------------------------
1037 // wxSocketBase pushback
1038 // --------------------------------------------------------------
1039
1040 void wxSocketBase::Pushback(const char *buffer, wxUint32 size)
1041 {
1042 if (m_unread == NULL)
1043 m_unread = (char *)malloc(size);
1044 else {
1045 char *tmp;
1046
1047 tmp = (char *)malloc(m_unrd_size + size);
1048 memcpy(tmp+size, m_unread, m_unrd_size);
1049 free(m_unread);
1050
1051 m_unread = tmp;
1052 }
1053
1054 m_unrd_size += size;
1055
1056 memcpy(m_unread, buffer, size);
1057 }
1058
1059 wxUint32 wxSocketBase::GetPushback(char *buffer, wxUint32 size, bool peek)
1060 {
1061 if (!m_unrd_size)
1062 return 0;
1063
1064 if (size > (m_unrd_size-m_unrd_cur))
1065 size = m_unrd_size-m_unrd_cur;
1066
1067 memcpy(buffer, (m_unread+m_unrd_cur), size);
1068
1069 if (!peek) {
1070 m_unrd_cur += size;
1071 if (m_unrd_size == m_unrd_cur) {
1072 free(m_unread);
1073 m_unread = NULL;
1074 m_unrd_size = 0;
1075 m_unrd_cur = 0;
1076 }
1077 }
1078
1079 return size;
1080 }
1081
1082 // --------------------------------------------------------------
1083 // wxSocketServer
1084 // --------------------------------------------------------------
1085
1086 // --------------------------------------------------------------
1087 // wxSocketServer ctor and dtor
1088 // --------------------------------------------------------------
1089
1090 wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
1091 wxSockFlags flags) :
1092 wxSocketBase(flags, SOCK_SERVER)
1093 {
1094 // Create the socket
1095 m_socket = GSocket_new();
1096
1097 if (!m_socket)
1098 return;
1099
1100 // Setup the socket as server
1101 GSocket_SetLocal(m_socket, addr_man.GetAddress());
1102 if (GSocket_SetServer(m_socket) != GSOCK_NOERROR)
1103 {
1104 GSocket_destroy(m_socket);
1105 m_socket = NULL;
1106 return;
1107 }
1108
1109 GSocket_SetTimeout(m_socket, m_timeout);
1110 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1111 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1112 wx_socket_callback, (char *)this);
1113
1114 }
1115
1116 // --------------------------------------------------------------
1117 // wxSocketServer Accept
1118 // --------------------------------------------------------------
1119
1120 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1121 {
1122 GSocket *child_socket;
1123
1124 if (!m_socket)
1125 return FALSE;
1126
1127 // GRG: If wait == FALSE, then the call should be nonblocking.
1128 // When we are finished, we put the socket to blocking mode
1129 // again.
1130
1131 if (!wait)
1132 GSocket_SetNonBlocking(m_socket, TRUE);
1133
1134 child_socket = GSocket_WaitConnection(m_socket);
1135
1136 if (!wait)
1137 GSocket_SetNonBlocking(m_socket, FALSE);
1138
1139 // GRG: this was not being handled!
1140 if (child_socket == NULL)
1141 return FALSE;
1142
1143 sock.m_type = SOCK_INTERNAL;
1144 sock.m_socket = child_socket;
1145 sock.m_connected = TRUE;
1146
1147 GSocket_SetTimeout(sock.m_socket, sock.m_timeout);
1148 GSocket_SetCallback(sock.m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1149 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1150 wx_socket_callback, (char *)&sock);
1151
1152 return TRUE;
1153 }
1154
1155 wxSocketBase *wxSocketServer::Accept(bool wait)
1156 {
1157 wxSocketBase* sock = new wxSocketBase();
1158
1159 sock->SetFlags((wxSockFlags)m_flags);
1160
1161 if (!AcceptWith(*sock, wait))
1162 return NULL;
1163
1164 return sock;
1165 }
1166
1167 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1168 {
1169 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1170 }
1171
1172 // --------------------------------------------------------------
1173 // wxSocketClient
1174 // --------------------------------------------------------------
1175
1176 // --------------------------------------------------------------
1177 // wxSocketClient ctor and dtor
1178 // --------------------------------------------------------------
1179
1180 wxSocketClient::wxSocketClient(wxSockFlags _flags) :
1181 wxSocketBase(_flags, SOCK_CLIENT)
1182 {
1183 }
1184
1185 wxSocketClient::~wxSocketClient()
1186 {
1187 }
1188
1189 // --------------------------------------------------------------
1190 // wxSocketClient Connect functions
1191 // --------------------------------------------------------------
1192 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
1193 {
1194 GSocketError err;
1195
1196 if (IsConnected())
1197 Close();
1198
1199 // This should never happen.
1200 if (m_socket)
1201 GSocket_destroy(m_socket);
1202
1203 // Initialize all socket stuff ...
1204 m_socket = GSocket_new();
1205 m_connected = FALSE;
1206 m_establishing = FALSE;
1207
1208 if (!m_socket)
1209 return FALSE;
1210
1211 GSocket_SetTimeout(m_socket, m_timeout);
1212 GSocket_SetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1213 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1214 wx_socket_callback, (char *)this);
1215
1216 // GRG: If wait == FALSE, then the call should be nonblocking.
1217 // When we are finished, we put the socket to blocking mode
1218 // again.
1219
1220 if (!wait)
1221 GSocket_SetNonBlocking(m_socket, TRUE);
1222
1223 GSocket_SetPeer(m_socket, addr_man.GetAddress());
1224 err = GSocket_Connect(m_socket, GSOCK_STREAMED);
1225
1226 if (!wait)
1227 GSocket_SetNonBlocking(m_socket, FALSE);
1228
1229 if (err != GSOCK_NOERROR)
1230 {
1231 if (err == GSOCK_WOULDBLOCK)
1232 m_establishing = TRUE;
1233
1234 return FALSE;
1235 }
1236
1237 m_connected = TRUE;
1238 return TRUE;
1239 }
1240
1241 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1242 {
1243 if (m_connected) // Already connected
1244 return TRUE;
1245
1246 if (!m_establishing || !m_socket) // No connection in progress
1247 return FALSE;
1248
1249 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1250 }
1251
1252 // --------------------------------------------------------------
1253 // wxSocketEvent
1254 // --------------------------------------------------------------
1255
1256 wxSocketEvent::wxSocketEvent(int id)
1257 : wxEvent(id)
1258 {
1259 wxEventType type = (wxEventType)wxEVT_SOCKET;
1260
1261 SetEventType(type);
1262 }
1263
1264 void wxSocketEvent::CopyObject(wxObject& obj_d) const
1265 {
1266 wxSocketEvent *event = (wxSocketEvent *)&obj_d;
1267
1268 wxEvent::CopyObject(obj_d);
1269
1270 event->m_skevt = m_skevt;
1271 event->m_socket = m_socket;
1272 }
1273
1274 // --------------------------------------------------------------------------
1275 // wxSocketModule
1276 // --------------------------------------------------------------------------
1277 class WXDLLEXPORT wxSocketModule: public wxModule {
1278 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1279 public:
1280 bool OnInit() {
1281 return GSocket_Init();
1282 }
1283 void OnExit() {
1284 GSocket_Cleanup();
1285 }
1286 };
1287
1288 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1289
1290 #endif
1291 // wxUSE_SOCKETS