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