1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
6 // Copyright: (C) 1999-1997, Guilhem Lavaux
7 // (C) 2000-1999, Guillermo Rodriguez Garcia
9 // License: see wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "socket.h"
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
25 // ==========================================================================
26 // Headers and constants
27 // ==========================================================================
31 #include "wx/object.h"
32 #include "wx/string.h"
35 #include "wx/module.h"
41 #include "wx/gdicmn.h" // for wxPendingDelete
44 #include "wx/sckaddr.h"
45 #include "wx/socket.h"
49 #define MAX_DISCARD_SIZE (10 * 1024)
51 // what to do within waits
52 #define PROCESS_EVENTS() wxYield()
54 // use wxPostEvent or not
55 #define USE_DELAYED_EVENTS 1
57 // --------------------------------------------------------------------------
59 // --------------------------------------------------------------------------
61 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
62 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
63 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
64 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
65 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
67 class wxSocketState
: public wxObject
71 wxSocketEventFlags m_neededreq
;
72 wxSocketFlags m_flags
;
73 wxSocketBase::wxSockCbk m_cbk
;
77 wxSocketState() : wxObject() {}
81 // ==========================================================================
83 // ==========================================================================
85 // --------------------------------------------------------------------------
87 // --------------------------------------------------------------------------
89 void wxSocketBase::Init()
92 m_type
= wxSOCKET_UNINIT
;
103 m_beingDeleted
= FALSE
;
113 m_notify_state
= FALSE
;
119 wxSocketBase::wxSocketBase() { Init(); }
121 wxSocketBase::wxSocketBase(wxSocketFlags flags
, wxSocketType type
)
129 wxSocketBase::~wxSocketBase()
131 // Just in case the app called Destroy() *and* then deleted
132 // the socket immediately: don't leave dangling pointers.
134 wxPendingDelete
.DeleteObject(this);
137 // Shutdown and close the socket
141 // Destroy the GSocket object
143 GSocket_destroy(m_socket
);
145 // Free the pushback buffer
150 bool wxSocketBase::Destroy()
152 // Delayed destruction: the socket will be deleted during the next
153 // idle loop iteration. This ensures that all pending events have
155 m_beingDeleted
= TRUE
;
157 // Shutdown and close the socket
161 if ( wxPendingDelete
.Member(this) )
162 wxPendingDelete
.Append(this);
171 // --------------------------------------------------------------------------
172 // Basic IO operations
173 // --------------------------------------------------------------------------
175 // The following IO operations update m_error and m_lcount:
176 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
178 // TODO: Should Connect, Accept and AcceptWith update m_error?
180 bool wxSocketBase::Close()
182 // Interrupt pending waits
188 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
189 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
191 // Shutdown the connection
192 GSocket_Shutdown(m_socket
);
196 m_establishing
= FALSE
;
200 wxSocketBase
& wxSocketBase::Read(char* buffer
, wxUint32 nbytes
)
205 m_lcount
= _Read(buffer
, nbytes
);
207 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
208 if (m_flags
& wxSOCKET_WAITALL
)
209 m_error
= (m_lcount
!= nbytes
);
211 m_error
= (m_lcount
== 0);
213 // Allow read events from now on
219 wxUint32
wxSocketBase::_Read(char* buffer
, wxUint32 nbytes
)
224 // Try the pushback buffer first
225 total
= GetPushback(buffer
, nbytes
, FALSE
);
229 // If the socket is invalid or we got all the data, return now
230 if (!m_socket
|| !nbytes
)
233 // Possible combinations (they are checked in this order)
235 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
240 if (m_flags
& wxSOCKET_NOWAIT
)
242 GSocket_SetNonBlocking(m_socket
, TRUE
);
243 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
244 GSocket_SetNonBlocking(m_socket
, FALSE
);
249 else if (m_flags
& wxSOCKET_WAITALL
)
251 while (ret
> 0 && nbytes
> 0)
253 if (!(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead())
256 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
268 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForRead())
270 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
280 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, wxUint32 nbytes
)
282 wxUint32 len
, len2
, sig
, total
;
287 unsigned char sig
[4];
288 unsigned char len
[4];
297 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
299 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
302 sig
= (wxUint32
)msg
.sig
[0];
303 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
304 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
305 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
307 if (sig
!= 0xfeeddead)
309 wxLogWarning( _("wxSocket: invalid signature in ReadMsg."));
313 len
= (wxUint32
)msg
.len
[0];
314 len
|= (wxUint32
)(msg
.len
[1] << 8);
315 len
|= (wxUint32
)(msg
.len
[2] << 16);
316 len
|= (wxUint32
)(msg
.len
[3] << 24);
326 // Don't attemp to read if the msg was zero bytes long.
329 total
= _Read(buffer
, len
);
336 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
339 // NOTE: discarded bytes don't add to m_lcount.
342 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
343 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
344 len2
-= (wxUint32
)discard_len
;
346 while ((discard_len
> 0) && len2
);
348 delete [] discard_buffer
;
353 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
356 sig
= (wxUint32
)msg
.sig
[0];
357 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
358 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
359 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
361 if (sig
!= 0xdeadfeed)
363 wxLogWarning( _("wxSocket: invalid signature in ReadMsg."));
379 wxSocketBase
& wxSocketBase::Peek(char* buffer
, wxUint32 nbytes
)
384 m_lcount
= _Read(buffer
, nbytes
);
385 Pushback(buffer
, m_lcount
);
387 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
388 if (m_flags
& wxSOCKET_WAITALL
)
389 m_error
= (m_lcount
!= nbytes
);
391 m_error
= (m_lcount
== 0);
393 // Allow read events again
399 wxSocketBase
& wxSocketBase::Write(const char *buffer
, wxUint32 nbytes
)
404 m_lcount
= _Write(buffer
, nbytes
);
406 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
407 if (m_flags
& wxSOCKET_WAITALL
)
408 m_error
= (m_lcount
!= nbytes
);
410 m_error
= (m_lcount
== 0);
412 // Allow write events again
418 wxUint32
wxSocketBase::_Write(const char *buffer
, wxUint32 nbytes
)
423 // If the socket is invalid, return immediately
427 // Possible combinations (they are checked in this order)
429 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
434 if (m_flags
& wxSOCKET_NOWAIT
)
436 GSocket_SetNonBlocking(m_socket
, TRUE
);
437 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
438 GSocket_SetNonBlocking(m_socket
, FALSE
);
443 else if (m_flags
& wxSOCKET_WAITALL
)
445 while (ret
> 0 && nbytes
> 0)
447 if (!(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite())
450 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
462 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForWrite())
464 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
474 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, wxUint32 nbytes
)
480 unsigned char sig
[4];
481 unsigned char len
[4];
490 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
492 msg
.sig
[0] = (unsigned char) 0xad;
493 msg
.sig
[1] = (unsigned char) 0xde;
494 msg
.sig
[2] = (unsigned char) 0xed;
495 msg
.sig
[3] = (unsigned char) 0xfe;
497 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
498 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
499 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
500 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
502 if (_Write((char *)&msg
, sizeof(msg
)) < sizeof(msg
))
505 total
= _Write(buffer
, nbytes
);
510 msg
.sig
[0] = (unsigned char) 0xed;
511 msg
.sig
[1] = (unsigned char) 0xfe;
512 msg
.sig
[2] = (unsigned char) 0xad;
513 msg
.sig
[3] = (unsigned char) 0xde;
514 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
516 if ((_Write((char *)&msg
, sizeof(msg
))) < sizeof(msg
))
530 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, wxUint32 nbytes
)
533 Pushback(buffer
, nbytes
);
541 wxSocketBase
& wxSocketBase::Discard()
544 char *buffer
= new char[MAX_DISCARD_SIZE
];
552 SetFlags(wxSOCKET_NOWAIT
);
556 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
559 while (ret
== MAX_DISCARD_SIZE
);
565 // Allow read events again
571 // --------------------------------------------------------------------------
573 // --------------------------------------------------------------------------
575 // All Wait functions poll the socket using GSocket_Select() to
576 // check for the specified combination of conditions, until one
577 // of these conditions become true, an error occurs, or the
578 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
579 // this won't block the GUI.
581 bool wxSocketBase::_Wait(long seconds
, long milliseconds
,
582 wxSocketEventFlags flags
)
584 GSocketEventFlags result
;
587 // Set this to TRUE to interrupt ongoing waits
590 // Check for valid socket
594 // Check for valid timeout value.
596 timeout
= seconds
* 1000 + milliseconds
;
598 timeout
= m_timeout
* 1000;
600 // Active polling (without using events)
602 // NOTE: this duplicates some of the code in OnRequest (lost
603 // connection and connection establishment handling) but
604 // this doesn't hurt. It has to be here because the event
605 // might be a bit delayed, and it has to be in OnRequest
606 // as well because maybe the Wait functions are not being
609 // Do this at least once (important if timeout == 0, when
610 // we are just polling). Also, if just polling, do not yield.
617 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
619 // Incoming connection (server) or connection established (client)
620 if (result
& GSOCK_CONNECTION_FLAG
)
623 m_establishing
= FALSE
;
627 // Data available or output buffer ready
628 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
634 if (result
& GSOCK_LOST_FLAG
)
637 m_establishing
= FALSE
;
638 return (flags
& GSOCK_LOST_FLAG
);
642 if ((!timeout
) || (chrono
.Time() > timeout
) || (m_interrupt
))
651 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
653 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
655 GSOCK_CONNECTION_FLAG
|
659 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
661 // Check pushback buffer before entering _Wait
665 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
666 // _Wait becuase of the semantics of WaitForRead: a return
667 // value of TRUE means that a GSocket_Read call will return
668 // immediately, not that there is actually data to read.
670 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
674 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
676 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
679 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
681 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
684 // --------------------------------------------------------------------------
686 // --------------------------------------------------------------------------
689 // Get local or peer address
692 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
699 peer
= GSocket_GetPeer(m_socket
);
700 addr_man
.SetAddress(peer
);
701 GAddress_destroy(peer
);
706 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
713 local
= GSocket_GetLocal(m_socket
);
714 addr_man
.SetAddress(local
);
715 GAddress_destroy(local
);
721 // Save and restore socket state
724 void wxSocketBase::SaveState()
726 wxSocketState
*state
;
728 state
= new wxSocketState();
730 state
->m_notify_state
= m_notify_state
;
731 state
->m_neededreq
= m_neededreq
;
732 state
->m_flags
= m_flags
;
733 state
->m_cbk
= m_cbk
;
734 state
->m_cdata
= m_cdata
;
736 m_states
.Append(state
);
739 void wxSocketBase::RestoreState()
742 wxSocketState
*state
;
744 node
= m_states
.Last();
748 state
= (wxSocketState
*)node
->Data();
750 SetFlags(state
->m_flags
);
751 m_cbk
= state
->m_cbk
;
752 m_cdata
= state
->m_cdata
;
753 m_neededreq
= state
->m_neededreq
;
754 Notify(state
->m_notify_state
);
764 void wxSocketBase::SetTimeout(long seconds
)
769 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
772 void wxSocketBase::SetFlags(wxSocketFlags flags
)
777 // --------------------------------------------------------------------------
778 // Callbacks (now obsolete - use events instead)
779 // --------------------------------------------------------------------------
781 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
783 wxSockCbk old_cbk
= cbk_
;
789 char *wxSocketBase::CallbackData(char *data
)
791 char *old_data
= m_cdata
;
797 // --------------------------------------------------------------------------
799 // --------------------------------------------------------------------------
801 // All events (INPUT, OUTPUT, CONNECTION, LOST) are now always
802 // internally watched; but users will only be notified of those
803 // events they are interested in.
805 static void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
809 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
811 sckobj
->OnRequest((wxSocketNotify
)event
);
814 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
819 void wxSocketBase::Notify(bool notify
)
821 m_notify_state
= notify
;
824 void wxSocketBase::OnRequest(wxSocketNotify req_evt
)
826 wxSocketEventFlags flag
= -1;
830 case GSOCK_INPUT
: flag
= GSOCK_INPUT_FLAG
; break;
831 case GSOCK_OUTPUT
: flag
= GSOCK_OUTPUT_FLAG
; break;
832 case GSOCK_CONNECTION
: flag
= GSOCK_CONNECTION_FLAG
; break;
833 case GSOCK_LOST
: flag
= GSOCK_LOST_FLAG
; break;
836 // This duplicates some code in _Wait, but this doesn't
837 // hurt. It has to be here because we don't know whether
838 // the Wait functions will be used, and it has to be in
839 // _Wait as well because the event might be a bit delayed.
843 case wxSOCKET_CONNECTION
:
844 m_establishing
= FALSE
;
848 // If we are in the middle of a R/W operation, do not
849 // propagate events to users. Also, filter 'late' events
850 // which are no longer valid.
853 if (m_reading
|| !GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
857 case wxSOCKET_OUTPUT
:
858 if (m_writing
|| !GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
))
864 m_establishing
= FALSE
;
871 if (((m_neededreq
& flag
) == flag
) && m_notify_state
)
875 wxSocketEvent
event(m_id
);
876 event
.m_socket
= this;
877 event
.m_event
= req_evt
;
879 #if USE_DELAYED_EVENTS
880 wxPostEvent(m_handler
, event
);
882 m_handler
->ProcessEvent(event
);
887 m_cbk(*this, req_evt
, m_cdata
);
891 void wxSocketBase::SetEventHandler(wxEvtHandler
& handler
, int id
)
893 m_handler
= &handler
;
897 // --------------------------------------------------------------------------
899 // --------------------------------------------------------------------------
901 void wxSocketBase::Pushback(const char *buffer
, wxUint32 size
)
905 if (m_unread
== NULL
)
906 m_unread
= (char *)malloc(size
);
911 tmp
= (char *)malloc(m_unrd_size
+ size
);
912 memcpy(tmp
+size
, m_unread
, m_unrd_size
);
920 memcpy(m_unread
, buffer
, size
);
923 wxUint32
wxSocketBase::GetPushback(char *buffer
, wxUint32 size
, bool peek
)
928 if (size
> (m_unrd_size
-m_unrd_cur
))
929 size
= m_unrd_size
-m_unrd_cur
;
931 memcpy(buffer
, (m_unread
+m_unrd_cur
), size
);
936 if (m_unrd_size
== m_unrd_cur
)
948 // ==========================================================================
950 // ==========================================================================
952 // --------------------------------------------------------------------------
954 // --------------------------------------------------------------------------
956 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
958 : wxSocketBase(flags
, wxSOCKET_SERVER
)
961 m_socket
= GSocket_new();
966 // Setup the socket as server
967 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
968 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
970 GSocket_destroy(m_socket
);
975 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
976 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
977 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
978 wx_socket_callback
, (char *)this);
982 // --------------------------------------------------------------------------
984 // --------------------------------------------------------------------------
986 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
988 GSocket
*child_socket
;
993 // If wait == FALSE, then the call should be nonblocking.
994 // When we are finished, we put the socket to blocking mode
998 GSocket_SetNonBlocking(m_socket
, TRUE
);
1000 child_socket
= GSocket_WaitConnection(m_socket
);
1003 GSocket_SetNonBlocking(m_socket
, FALSE
);
1008 sock
.m_type
= wxSOCKET_BASE
;
1009 sock
.m_socket
= child_socket
;
1010 sock
.m_connected
= TRUE
;
1012 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
* 1000);
1013 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1014 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1015 wx_socket_callback
, (char *)&sock
);
1020 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1022 wxSocketBase
* sock
= new wxSocketBase();
1024 sock
->SetFlags(m_flags
);
1026 if (!AcceptWith(*sock
, wait
))
1032 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1034 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1037 // ==========================================================================
1039 // ==========================================================================
1041 // --------------------------------------------------------------------------
1043 // --------------------------------------------------------------------------
1045 wxSocketClient::wxSocketClient(wxSocketFlags flags
)
1046 : wxSocketBase(flags
, wxSOCKET_CLIENT
)
1050 wxSocketClient::~wxSocketClient()
1054 // --------------------------------------------------------------------------
1056 // --------------------------------------------------------------------------
1058 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1064 // Shutdown and destroy the socket
1066 GSocket_destroy(m_socket
);
1069 m_socket
= GSocket_new();
1070 m_connected
= FALSE
;
1071 m_establishing
= FALSE
;
1076 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1077 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1078 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1079 wx_socket_callback
, (char *)this);
1081 // If wait == FALSE, then the call should be nonblocking.
1082 // When we are finished, we put the socket to blocking mode
1086 GSocket_SetNonBlocking(m_socket
, TRUE
);
1088 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1089 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1092 GSocket_SetNonBlocking(m_socket
, FALSE
);
1094 if (err
!= GSOCK_NOERROR
)
1096 if (err
== GSOCK_WOULDBLOCK
)
1097 m_establishing
= TRUE
;
1106 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1108 if (m_connected
) // Already connected
1111 if (!m_establishing
|| !m_socket
) // No connection in progress
1114 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
|
1118 // ==========================================================================
1120 // ==========================================================================
1122 /* NOTE: experimental stuff - might change */
1124 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
,
1125 wxSocketFlags flags
)
1126 : wxSocketBase( flags
, wxSOCKET_DATAGRAM
)
1128 // Create the socket
1129 m_socket
= GSocket_new();
1134 // Setup the socket as non connection oriented
1135 GSocket_SetLocal(m_socket
, addr
.GetAddress());
1136 if( GSocket_SetNonOriented(m_socket
) != GSOCK_NOERROR
)
1138 GSocket_destroy(m_socket
);
1143 // Initialize all stuff
1144 m_connected
= FALSE
;
1145 m_establishing
= FALSE
;
1146 GSocket_SetTimeout( m_socket
, m_timeout
);
1147 GSocket_SetCallback( m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1148 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1149 wx_socket_callback
, (char*)this );
1153 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1162 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1166 GSocket_SetPeer(m_socket
, addr
.GetAddress());
1171 // ==========================================================================
1173 // ==========================================================================
1175 wxSocketEvent::wxSocketEvent(int id
) : wxEvent(id
)
1177 SetEventType( (wxEventType
)wxEVT_SOCKET
);
1180 void wxSocketEvent::CopyObject(wxObject
& object_dest
) const
1182 wxSocketEvent
*event
= (wxSocketEvent
*)&object_dest
;
1184 wxEvent::CopyObject(object_dest
);
1186 event
->m_event
= m_event
;
1187 event
->m_socket
= m_socket
;
1191 // ==========================================================================
1193 // ==========================================================================
1195 class WXDLLEXPORT wxSocketModule
: public wxModule
1197 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1200 bool OnInit() { return GSocket_Init(); }
1201 void OnExit() { GSocket_Cleanup(); }
1204 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)