1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
6 // Updated: September 1999
7 // Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
8 // (C) 1999, Guillermo Rodriguez Garcia
10 // License: see wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
14 #pragma implementation "socket.h"
17 // For compilers that support precompilation, includes "wx.h".
18 #include "wx/wxprec.h"
26 /////////////////////////////////////////////////////////////////////////////
28 /////////////////////////////////////////////////////////////////////////////
30 #include "wx/object.h"
31 #include "wx/string.h"
34 #include "wx/module.h"
42 /////////////////////////////////////////////////////////////////////////////
44 /////////////////////////////////////////////////////////////////////////////
45 #include "wx/sckaddr.h"
46 #include "wx/socket.h"
49 #if defined(__WXMSW__) || defined(__WXPM__) || defined(__WXMOTIF__) || defined(__WXMAC__)
50 #define PROCESS_EVENTS() wxYield()
51 #elif defined(__WXGTK__)
53 #define PROCESS_EVENTS() gtk_main_iteration()
57 // --------------------------------------------------------------
59 // --------------------------------------------------------------
60 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
61 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
62 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
63 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
65 class wxSocketState
: public wxObject
69 GSocketEventFlags evt_notify_state
;
70 wxSockFlags socket_flags
;
71 wxSocketBase::wxSockCbk c_callback
;
72 char *c_callback_data
;
75 wxSocketState() : wxObject() {}
78 // --------------------------------------------------------------
79 // wxSocketBase ctor and dtor
80 // --------------------------------------------------------------
82 wxSocketBase::wxSocketBase(wxSockFlags _flags
, wxSockType _type
) :
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
)
96 wxSocketBase::wxSocketBase() :
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
)
110 wxSocketBase::~wxSocketBase()
115 // Shutdown and close the socket
118 // Destroy the GSocket object
120 GSocket_destroy(m_socket
);
123 bool wxSocketBase::Close()
128 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
129 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
131 // Shutdown the connection
132 GSocket_Shutdown(m_socket
);
134 m_establishing
= FALSE
;
140 // --------------------------------------------------------------
141 // wxSocketBase basic IO operations
142 // --------------------------------------------------------------
144 // All IO operations {Read, Write, ReadMsg, WriteMsg, Peek,
145 // Unread, Discard} update m_error and m_lcount.
147 // TODO: Should Connect, Accept and AcceptWith update m_error?
149 class _wxSocketInternalTimer
: public wxTimer
153 unsigned long m_new_val
;
157 *m_state
= (int)m_new_val
; // Change the value
161 wxUint32
wxSocketBase::DeferRead(char *buffer
, wxUint32 nbytes
)
164 _wxSocketInternalTimer timer
;
166 //wxLogMessage("Entrando a DeferRead, nbytes = %d", nbytes);
167 wxASSERT(m_defering
== NO_DEFER
);
169 // Set the defering mode to READ.
170 m_defering
= DEFER_READ
;
172 // Set the current buffer.
173 m_defer_buffer
= buffer
;
174 m_defer_nbytes
= nbytes
;
175 m_defer_timer
= &timer
;
177 timer
.m_state
= (int *)&m_defer_buffer
;
180 timer
.Start((int)(m_timeout
* 1000), FALSE
);
182 // If the socket is readable, call DoDefer for the first time
183 if (GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
185 //wxLogMessage("Llamando al primer DoDefer");
189 // Wait for buffer completion.
190 while (m_defer_buffer
!= NULL
)
195 // Disable defering mode.
196 m_defering
= NO_DEFER
;
197 m_defer_timer
= NULL
;
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
;
204 wxSocketBase
& wxSocketBase::Read(char* buffer
, wxUint32 nbytes
)
209 m_lcount
= _Read(buffer
, nbytes
);
211 // If in WAITALL mode, all bytes should have been read.
212 if (m_flags
& WAITALL
)
213 m_error
= (m_lcount
!= nbytes
);
215 m_error
= (m_lcount
== 0);
217 // Trigger another read event if there is still data available.
224 wxUint32
wxSocketBase::_Read(char* buffer
, wxUint32 nbytes
)
229 // we try this even if the connection has already been closed.
230 total
= GetPushback(buffer
, nbytes
, FALSE
);
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
)
239 // Possible combinations (they are checked in this order)
246 if (m_flags
& NOWAIT
) // NOWAIT
248 GSocket_SetNonBlocking(m_socket
, TRUE
);
249 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
250 GSocket_SetNonBlocking(m_socket
, FALSE
);
255 else if ((m_flags
& SPEED
) && (m_flags
& WAITALL
)) // SPEED, WAITALL
257 while (ret
> 0 && nbytes
> 0)
259 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
264 // In case the last call was an error ...
268 else if (m_flags
& SPEED
) // SPEED, !WAITALL
270 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
275 else // NONE or WAITALL
277 ret
= DeferRead(buffer
, nbytes
);
286 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, wxUint32 nbytes
)
288 #define MAX_DISCARD_SIZE (10 * 1024)
290 wxUint32 len
, len2
, sig
, total
;
295 unsigned char sig
[4];
296 unsigned char len
[4];
305 SetFlags((m_flags
& SPEED
) | WAITALL
);
307 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
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);
315 if (sig
!= 0xfeeddead)
317 wxLogWarning( _("TCP: invalid signature returned to ReadMsg."));
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);
326 //wxLogMessage("Readmsg: %d %d %d %d -> len == %d",
327 // msg.len[0], msg.len[1], msg.len[2], msg.len[3], len);
337 // This check is necessary so that we don't attemp to read if
338 // the msg was zero bytes long.
341 total
= _Read(buffer
, len
);
348 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
351 // NOTE: discarded bytes don't add to m_lcount.
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
;
358 while ((discard_len
> 0) && len2
);
360 delete [] discard_buffer
;
365 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
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);
373 if (sig
!= 0xdeadfeed)
375 //wxLogMessage(wxT("Warning: invalid signature returned to ReadMsg"));
391 #undef MAX_DISCARD_SIZE
394 wxSocketBase
& wxSocketBase::Peek(char* buffer
, wxUint32 nbytes
)
399 m_lcount
= _Read(buffer
, nbytes
);
400 Pushback(buffer
, nbytes
);
402 // If in WAITALL mode, all bytes should have been read.
403 if (m_flags
& WAITALL
)
404 m_error
= (m_lcount
!= nbytes
);
406 m_error
= (m_lcount
== 0);
408 // Trigger another read event if there is still data available.
415 wxUint32
wxSocketBase::DeferWrite(const char *buffer
, wxUint32 nbytes
)
418 _wxSocketInternalTimer timer
;
420 wxASSERT(m_defering
== NO_DEFER
);
421 //wxLogMessage("Entrando a DeferWrite");
423 m_defering
= DEFER_WRITE
;
425 // Set the current buffer
426 m_defer_buffer
= (char *)buffer
;
427 m_defer_nbytes
= nbytes
;
428 m_defer_timer
= &timer
;
431 timer
.m_state
= (int *)&m_defer_buffer
;
434 timer
.Start((int)(m_timeout
* 1000), FALSE
);
436 // If the socket is writable, call DoDefer for the first time
437 if (GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
))
439 //wxLogMessage("Llamando al primer DoDefer");
443 // Wait for buffer completion.
444 while (m_defer_buffer
!= NULL
)
449 // Disable defering mode
450 m_defer_timer
= NULL
;
451 m_defering
= NO_DEFER
;
454 //s.Printf(wxT("Saliendo de DeferWrite: total %d bytes"), nbytes-m_defer_nbytes);
457 return nbytes
-m_defer_nbytes
;
460 wxSocketBase
& wxSocketBase::Write(const char *buffer
, wxUint32 nbytes
)
465 m_lcount
= _Write(buffer
, nbytes
);
467 // If in WAITALL mode, all bytes should have been written.
468 if (m_flags
& WAITALL
)
469 m_error
= (m_lcount
!= nbytes
);
471 m_error
= (m_lcount
== 0);
473 // Trigger another write event if the socket is still writable
476 // TODO: TriggerWrite
480 wxUint32
wxSocketBase::_Write(const char *buffer
, wxUint32 nbytes
)
485 if (!m_connected
|| !m_socket
)
488 // Possible combinations (they are checked in this order)
495 if (m_flags
& NOWAIT
) // NOWAIT
497 GSocket_SetNonBlocking(m_socket
, TRUE
);
498 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
499 GSocket_SetNonBlocking(m_socket
, FALSE
);
504 else if ((m_flags
& SPEED
) && (m_flags
& WAITALL
)) // SPEED, WAITALL
506 while (ret
> 0 && nbytes
> 0)
508 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
513 // In case the last call was an error ...
517 else if (m_flags
& SPEED
) // SPEED, !WAITALL
519 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
524 else // NONE or WAITALL
526 ret
= DeferWrite(buffer
, nbytes
);
535 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, wxUint32 nbytes
)
541 unsigned char sig
[4];
542 unsigned char len
[4];
551 SetFlags((m_flags
& SPEED
) | WAITALL
);
553 // warning about 'cast truncates constant value'
555 # pragma warning(disable: 4310)
556 #endif // __VISUALC__
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;
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;
568 //wxLogMessage("Writemsg: %d %d %d %d -> %d",
570 // (nbytes >> 8) & 0xff,
571 // (nbytes >> 16) & 0xff,
572 // (nbytes >> 24) & 0xff,
576 if (_Write((char *)&msg
, sizeof(msg
)) < sizeof(msg
))
579 total
= _Write(buffer
, nbytes
);
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;
590 if ((_Write((char *)&msg
, sizeof(msg
))) < sizeof(msg
))
601 // TODO: TriggerWrite
605 # pragma warning(default: 4310)
606 #endif // __VISUALC__
609 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, wxUint32 nbytes
)
612 Pushback(buffer
, nbytes
);
620 void wxSocketBase::DoDefer()
630 ret
= GSocket_Read(m_socket
, m_defer_buffer
, m_defer_nbytes
);
633 ret
= GSocket_Write(m_socket
, m_defer_buffer
, m_defer_nbytes
);
640 m_defer_nbytes
-= ret
;
642 // If we are waiting for all bytes to be acquired, keep the defering
644 if (!(m_flags
& WAITALL
) || !m_defer_nbytes
|| ret
< 0)
646 m_defer_buffer
= NULL
;
650 m_defer_buffer
+= ret
;
651 m_defer_timer
->Start((int)(m_timeout
* 1000), FALSE
);
654 //wxLogMessage("DoDefer ha transferido %d bytes", ret);
657 wxSocketBase
& wxSocketBase::Discard()
659 #define MAX_BUFSIZE (10*1024)
662 char *my_data
= new char[MAX_BUFSIZE
];
663 wxUint32 recv_size
= MAX_BUFSIZE
;
672 while (recv_size
== MAX_BUFSIZE
)
674 recv_size
= _Read(my_data
, MAX_BUFSIZE
);
682 // Trigger another read event if there is still data available.
691 // --------------------------------------------------------------
692 // wxSocketBase get local or peer addresses
693 // --------------------------------------------------------------
695 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
702 peer
= GSocket_GetPeer(m_socket
);
703 addr_man
.SetAddress(peer
);
704 GAddress_destroy(peer
);
709 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
716 local
= GSocket_GetLocal(m_socket
);
717 addr_man
.SetAddress(local
);
718 GAddress_destroy(local
);
723 // --------------------------------------------------------------
724 // wxSocketBase save and restore socket state
725 // --------------------------------------------------------------
727 void wxSocketBase::SaveState()
729 wxSocketState
*state
;
731 state
= new wxSocketState();
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
;
739 m_states
.Append(state
);
742 void wxSocketBase::RestoreState()
745 wxSocketState
*state
;
747 node
= m_states
.Last();
751 state
= (wxSocketState
*)node
->Data();
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
);
764 // --------------------------------------------------------------
765 // wxSocketBase Wait functions
766 // --------------------------------------------------------------
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.
775 bool wxSocketBase::_Wait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
777 GSocketEventFlags result
;
778 _wxSocketInternalTimer timer
;
782 // Check for valid socket
786 // If it is not a server, it must be connected or establishing connection
787 if ((m_type
!= SOCK_SERVER
) && (!m_connected
&& !m_establishing
))
790 // Check for valid timeout value
792 timeout
= seconds
* 1000 + milliseconds
;
794 timeout
= m_timeout
* 1000;
799 timer
.m_state
= &state
;
801 timer
.Start((int)timeout
, TRUE
);
804 // Active polling (without using events)
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.
812 // Do this at least once (important if timeout == 0, when
813 // we are just polling)
816 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
819 if (result
& GSOCK_LOST_FLAG
)
822 m_defer_buffer
= NULL
;
827 // Incoming connection (server) or connection established (client)
828 if (result
& GSOCK_CONNECTION_FLAG
)
832 m_establishing
= FALSE
;
836 // If we are in the middle of a R/W operation, do not propagate
838 if ( ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
839 && (!m_writing
) && (!m_reading
) )
842 if (m_defer_buffer == NULL)
853 while ((state
== -1) && timeout
);
859 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
861 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
863 GSOCK_CONNECTION_FLAG
|
867 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
869 // Check pushback buffer
873 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
);
876 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
878 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
881 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
883 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
886 void wxSocketBase::SetTimeout(long seconds
)
891 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
894 // --------------------------------------------------------------
895 // wxSocketBase flags
896 // --------------------------------------------------------------
898 void wxSocketBase::SetFlags(wxSockFlags _flags
)
903 // --------------------------------------------------------------
904 // wxSocketBase callback management
905 // --------------------------------------------------------------
907 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
909 wxSockCbk old_cbk
= cbk_
;
915 char *wxSocketBase::CallbackData(char *data
)
917 char *old_data
= m_cdata
;
923 // --------------------------------------------------------------
924 // wxSocketBase automatic notifier
925 // --------------------------------------------------------------
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.
931 static void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
932 GSocketEvent event
, char *cdata
)
934 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
936 sckobj
->OnRequest((wxSocketNotify
)event
);
939 wxSocketEventFlags
wxSocketBase::EventToNotify(wxSocketNotify evt
)
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
;
951 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
956 void wxSocketBase::Notify(bool notify
)
958 m_notify_state
= notify
;
961 void wxSocketBase::OnRequest(wxSocketNotify req_evt
)
963 wxSocketEvent
event(m_id
);
964 wxSocketEventFlags flag
= EventToNotify(req_evt
);
966 // fprintf(stderr, "%s: Entering OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
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.
976 case wxSOCKET_CONNECTION
:
977 m_establishing
= FALSE
;
981 m_defer_buffer
= NULL
;
985 case wxSOCKET_OUTPUT
:
988 // fprintf(stderr, "%s: Habia buffer, evt %d skipped\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
990 // Do not notify to user
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
))
1001 // fprintf(stderr, "%s: Swallowed evt %d\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
1005 if (((m_neededreq
& flag
) == flag
) && m_notify_state
)
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
);
1014 m_cbk(*this, req_evt
, m_cdata
);
1017 // fprintf(stderr, "%s: Exiting OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
1020 void wxSocketBase::OldOnNotify(wxSocketNotify
WXUNUSED(evt
))
1024 // --------------------------------------------------------------
1025 // wxSocketBase set event handler
1026 // --------------------------------------------------------------
1028 void wxSocketBase::SetEventHandler(wxEvtHandler
& h_evt
, int id
)
1030 SetNextHandler(&h_evt
);
1034 // --------------------------------------------------------------
1035 // wxSocketBase pushback
1036 // --------------------------------------------------------------
1038 void wxSocketBase::Pushback(const char *buffer
, wxUint32 size
)
1040 if (m_unread
== NULL
)
1041 m_unread
= (char *)malloc(size
);
1045 tmp
= (char *)malloc(m_unrd_size
+ size
);
1046 memcpy(tmp
+size
, m_unread
, m_unrd_size
);
1052 m_unrd_size
+= size
;
1054 memcpy(m_unread
, buffer
, size
);
1057 wxUint32
wxSocketBase::GetPushback(char *buffer
, wxUint32 size
, bool peek
)
1062 if (size
> (m_unrd_size
-m_unrd_cur
))
1063 size
= m_unrd_size
-m_unrd_cur
;
1065 memcpy(buffer
, (m_unread
+m_unrd_cur
), size
);
1069 if (m_unrd_size
== m_unrd_cur
) {
1080 // --------------------------------------------------------------
1082 // --------------------------------------------------------------
1084 // --------------------------------------------------------------
1085 // wxSocketServer ctor and dtor
1086 // --------------------------------------------------------------
1088 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
1089 wxSockFlags flags
) :
1090 wxSocketBase(flags
, SOCK_SERVER
)
1092 // Create the socket
1093 m_socket
= GSocket_new();
1098 // Setup the socket as server
1099 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
1100 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
1102 GSocket_destroy(m_socket
);
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);
1114 // --------------------------------------------------------------
1115 // wxSocketServer Accept
1116 // --------------------------------------------------------------
1118 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1120 GSocket
*child_socket
;
1125 // GRG: If wait == FALSE, then the call should be nonblocking.
1126 // When we are finished, we put the socket to blocking mode
1130 GSocket_SetNonBlocking(m_socket
, TRUE
);
1132 child_socket
= GSocket_WaitConnection(m_socket
);
1135 GSocket_SetNonBlocking(m_socket
, FALSE
);
1137 // GRG: this was not being handled!
1138 if (child_socket
== NULL
)
1141 sock
.m_type
= SOCK_INTERNAL
;
1142 sock
.m_socket
= child_socket
;
1143 sock
.m_connected
= TRUE
;
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
);
1153 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1155 wxSocketBase
* sock
= new wxSocketBase();
1157 sock
->SetFlags((wxSockFlags
)m_flags
);
1159 if (!AcceptWith(*sock
, wait
))
1165 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1167 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1170 // --------------------------------------------------------------
1172 // --------------------------------------------------------------
1174 // --------------------------------------------------------------
1175 // wxSocketClient ctor and dtor
1176 // --------------------------------------------------------------
1178 wxSocketClient::wxSocketClient(wxSockFlags _flags
) :
1179 wxSocketBase(_flags
, SOCK_CLIENT
)
1183 wxSocketClient::~wxSocketClient()
1187 // --------------------------------------------------------------
1188 // wxSocketClient Connect functions
1189 // --------------------------------------------------------------
1190 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1197 // This should never happen.
1199 GSocket_destroy(m_socket
);
1201 // Initialize all socket stuff ...
1202 m_socket
= GSocket_new();
1203 m_connected
= FALSE
;
1204 m_establishing
= FALSE
;
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);
1214 // GRG: If wait == FALSE, then the call should be nonblocking.
1215 // When we are finished, we put the socket to blocking mode
1219 GSocket_SetNonBlocking(m_socket
, TRUE
);
1221 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1222 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1225 GSocket_SetNonBlocking(m_socket
, FALSE
);
1227 if (err
!= GSOCK_NOERROR
)
1229 if (err
== GSOCK_WOULDBLOCK
)
1230 m_establishing
= TRUE
;
1239 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1241 if (m_connected
) // Already connected
1244 if (!m_establishing
|| !m_socket
) // No connection in progress
1247 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1250 // --------------------------------------------------------------
1252 // --------------------------------------------------------------
1254 wxSocketEvent::wxSocketEvent(int id
)
1257 wxEventType type
= (wxEventType
)wxEVT_SOCKET
;
1262 void wxSocketEvent::CopyObject(wxObject
& obj_d
) const
1264 wxSocketEvent
*event
= (wxSocketEvent
*)&obj_d
;
1266 wxEvent::CopyObject(obj_d
);
1268 event
->m_skevt
= m_skevt
;
1269 event
->m_socket
= m_socket
;
1272 // --------------------------------------------------------------------------
1274 // --------------------------------------------------------------------------
1275 class WXDLLEXPORT wxSocketModule
: public wxModule
{
1276 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1279 return GSocket_Init();
1286 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)