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"
38 #include "wx/gdicmn.h" // for wxPendingDelete
40 #include "wx/sckaddr.h"
41 #include "wx/socket.h"
45 #define MAX_DISCARD_SIZE (10 * 1024)
47 // what to do within waits
48 #define PROCESS_EVENTS() wxYield()
50 // use wxPostEvent or not
51 #define USE_DELAYED_EVENTS 1
53 // --------------------------------------------------------------------------
55 // --------------------------------------------------------------------------
57 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
58 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
59 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
60 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
61 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
63 class wxSocketState
: public wxObject
67 wxSocketEventFlags m_neededreq
;
69 wxSocketBase::wxSockCbk m_cbk
;
73 wxSocketState() : wxObject() {}
77 // ==========================================================================
79 // ==========================================================================
81 // --------------------------------------------------------------------------
83 // --------------------------------------------------------------------------
85 wxSocketBase::wxSocketBase(wxSockFlags _flags
, wxSockType _type
) :
87 m_socket(NULL
), m_evt_handler(NULL
), m_id(-1),
88 m_flags(_flags
), m_type(_type
),
89 m_neededreq(0), m_notify_state(FALSE
),
90 m_connected(FALSE
), m_establishing(FALSE
),
91 m_reading(FALSE
), m_writing(FALSE
),
92 m_error(FALSE
), m_lcount(0), m_timeout(600), m_states(),
93 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
94 m_cbk(NULL
), m_cdata(NULL
)
98 wxSocketBase::wxSocketBase() :
100 m_socket(NULL
), m_evt_handler(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_cbk(NULL
), m_cdata(NULL
)
111 wxSocketBase::~wxSocketBase()
116 // Shutdown and close the socket
119 // Destroy the GSocket object
121 GSocket_destroy(m_socket
);
125 bool wxSocketBase::Destroy()
127 // Delayed destruction: the socket will be deleted during the next
128 // idle loop iteration. This ensures that all pending events have
131 m_beingDeleted = TRUE;
134 if ( !wxPendingDelete.Member(this) )
135 wxPendingDelete.Append(this);
141 // --------------------------------------------------------------------------
142 // Basic IO operations
143 // --------------------------------------------------------------------------
145 // The following IO operations update m_error and m_lcount:
146 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
148 // TODO: Should Connect, Accept and AcceptWith update m_error?
150 bool wxSocketBase::Close()
152 // Interrupt pending waits
158 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
159 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
161 // Shutdown the connection
162 GSocket_Shutdown(m_socket
);
166 m_establishing
= FALSE
;
170 wxSocketBase
& wxSocketBase::Read(char* buffer
, wxUint32 nbytes
)
175 m_lcount
= _Read(buffer
, nbytes
);
177 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
178 if (m_flags
& wxSOCKET_WAITALL
)
179 m_error
= (m_lcount
!= nbytes
);
181 m_error
= (m_lcount
== 0);
183 // Allow read events from now on
189 wxUint32
wxSocketBase::_Read(char* buffer
, wxUint32 nbytes
)
194 // Try the pushback buffer first
195 total
= GetPushback(buffer
, nbytes
, FALSE
);
199 // If the socket is invalid or we got all the data, return now
200 if (!m_socket
|| !nbytes
)
203 // Possible combinations (they are checked in this order)
205 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
210 if (m_flags
& wxSOCKET_NOWAIT
)
212 GSocket_SetNonBlocking(m_socket
, TRUE
);
213 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
214 GSocket_SetNonBlocking(m_socket
, FALSE
);
219 else if (m_flags
& wxSOCKET_WAITALL
)
221 while (ret
> 0 && nbytes
> 0)
223 if (!(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead())
226 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
238 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForRead())
240 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
250 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, wxUint32 nbytes
)
252 wxUint32 len
, len2
, sig
, total
;
257 unsigned char sig
[4];
258 unsigned char len
[4];
267 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
269 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
272 sig
= (wxUint32
)msg
.sig
[0];
273 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
274 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
275 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
277 if (sig
!= 0xfeeddead)
279 wxLogWarning( _("wxSocket: invalid signature in ReadMsg."));
283 len
= (wxUint32
)msg
.len
[0];
284 len
|= (wxUint32
)(msg
.len
[1] << 8);
285 len
|= (wxUint32
)(msg
.len
[2] << 16);
286 len
|= (wxUint32
)(msg
.len
[3] << 24);
296 // Don't attemp to read if the msg was zero bytes long.
299 total
= _Read(buffer
, len
);
306 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
309 // NOTE: discarded bytes don't add to m_lcount.
312 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
313 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
314 len2
-= (wxUint32
)discard_len
;
316 while ((discard_len
> 0) && len2
);
318 delete [] discard_buffer
;
323 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
326 sig
= (wxUint32
)msg
.sig
[0];
327 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
328 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
329 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
331 if (sig
!= 0xdeadfeed)
333 wxLogWarning( _("wxSocket: invalid signature in ReadMsg."));
349 wxSocketBase
& wxSocketBase::Peek(char* buffer
, wxUint32 nbytes
)
354 m_lcount
= _Read(buffer
, nbytes
);
355 Pushback(buffer
, m_lcount
);
357 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
358 if (m_flags
& wxSOCKET_WAITALL
)
359 m_error
= (m_lcount
!= nbytes
);
361 m_error
= (m_lcount
== 0);
363 // Allow read events again
369 wxSocketBase
& wxSocketBase::Write(const char *buffer
, wxUint32 nbytes
)
374 m_lcount
= _Write(buffer
, nbytes
);
376 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
377 if (m_flags
& wxSOCKET_WAITALL
)
378 m_error
= (m_lcount
!= nbytes
);
380 m_error
= (m_lcount
== 0);
382 // Allow write events again
388 wxUint32
wxSocketBase::_Write(const char *buffer
, wxUint32 nbytes
)
393 // If the socket is invalid, return immediately
397 // Possible combinations (they are checked in this order)
399 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
404 if (m_flags
& wxSOCKET_NOWAIT
)
406 GSocket_SetNonBlocking(m_socket
, TRUE
);
407 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
408 GSocket_SetNonBlocking(m_socket
, FALSE
);
413 else if (m_flags
& wxSOCKET_WAITALL
)
415 while (ret
> 0 && nbytes
> 0)
417 if (!(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite())
420 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
432 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForWrite())
434 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
444 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, wxUint32 nbytes
)
450 unsigned char sig
[4];
451 unsigned char len
[4];
460 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
462 msg
.sig
[0] = (unsigned char) 0xad;
463 msg
.sig
[1] = (unsigned char) 0xde;
464 msg
.sig
[2] = (unsigned char) 0xed;
465 msg
.sig
[3] = (unsigned char) 0xfe;
467 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
468 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
469 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
470 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
472 if (_Write((char *)&msg
, sizeof(msg
)) < sizeof(msg
))
475 total
= _Write(buffer
, nbytes
);
480 msg
.sig
[0] = (unsigned char) 0xed;
481 msg
.sig
[1] = (unsigned char) 0xfe;
482 msg
.sig
[2] = (unsigned char) 0xad;
483 msg
.sig
[3] = (unsigned char) 0xde;
484 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
486 if ((_Write((char *)&msg
, sizeof(msg
))) < sizeof(msg
))
500 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, wxUint32 nbytes
)
503 Pushback(buffer
, nbytes
);
511 wxSocketBase
& wxSocketBase::Discard()
514 char *buffer
= new char[MAX_DISCARD_SIZE
];
522 SetFlags(wxSOCKET_NOWAIT
);
526 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
529 while (ret
== MAX_DISCARD_SIZE
);
535 // Allow read events again
541 // --------------------------------------------------------------------------
543 // --------------------------------------------------------------------------
545 // All Wait functions poll the socket using GSocket_Select() to
546 // check for the specified combination of conditions, until one
547 // of these conditions become true, an error occurs, or the
548 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
549 // this won't block the GUI.
551 class _wxSocketInternalTimer
: public wxTimer
555 unsigned long m_new_val
;
559 *m_state
= (int)m_new_val
; // Change the value
563 bool wxSocketBase::_Wait(long seconds
, long milliseconds
,
564 wxSocketEventFlags flags
)
566 GSocketEventFlags result
;
567 _wxSocketInternalTimer timer
;
571 // Set this to TRUE to interrupt ongoing waits
574 // Check for valid socket
578 // Check for valid timeout value
580 timeout
= seconds
* 1000 + milliseconds
;
582 timeout
= m_timeout
* 1000;
587 timer
.m_state
= &state
;
589 timer
.Start((int)timeout
, TRUE
);
592 // Active polling (without using events)
594 // NOTE: this duplicates some of the code in OnRequest (lost
595 // connection and connection establishment handling) but
596 // this doesn't hurt. It has to be here because the event
597 // might be a bit delayed, and it has to be in OnRequest
598 // as well because maybe the Wait functions are not being
601 // Do this at least once (important if timeout == 0, when
602 // we are just polling). Also, if just polling, do not yield.
606 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
608 // Incoming connection (server) or connection established (client)
609 if (result
& GSOCK_CONNECTION_FLAG
)
613 m_establishing
= FALSE
;
617 // Data available or output buffer ready
618 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
625 if (result
& GSOCK_LOST_FLAG
)
629 m_establishing
= FALSE
;
630 return (flags
& GSOCK_LOST_FLAG
);
634 if ((timeout
== 0) || (m_interrupt
))
644 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
646 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
648 GSOCK_CONNECTION_FLAG
|
652 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
654 // Check pushback buffer before entering _Wait
658 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
659 // _Wait becuase of the semantics of WaitForRead: a return
660 // value of TRUE means that a GSocket_Read call will return
661 // immediately, not that there is actually data to read.
663 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
667 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
669 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
672 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
674 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
677 // --------------------------------------------------------------------------
679 // --------------------------------------------------------------------------
682 // Get local or peer address
685 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
692 peer
= GSocket_GetPeer(m_socket
);
693 addr_man
.SetAddress(peer
);
694 GAddress_destroy(peer
);
699 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
706 local
= GSocket_GetLocal(m_socket
);
707 addr_man
.SetAddress(local
);
708 GAddress_destroy(local
);
714 // Save and restore socket state
717 void wxSocketBase::SaveState()
719 wxSocketState
*state
;
721 state
= new wxSocketState();
723 state
->m_notify_state
= m_notify_state
;
724 state
->m_neededreq
= m_neededreq
;
725 state
->m_flags
= m_flags
;
726 state
->m_cbk
= m_cbk
;
727 state
->m_cdata
= m_cdata
;
729 m_states
.Append(state
);
732 void wxSocketBase::RestoreState()
735 wxSocketState
*state
;
737 node
= m_states
.Last();
741 state
= (wxSocketState
*)node
->Data();
743 SetFlags(state
->m_flags
);
744 m_cbk
= state
->m_cbk
;
745 m_cdata
= state
->m_cdata
;
746 m_neededreq
= state
->m_neededreq
;
747 Notify(state
->m_notify_state
);
757 void wxSocketBase::SetTimeout(long seconds
)
762 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
765 void wxSocketBase::SetFlags(wxSockFlags _flags
)
770 // --------------------------------------------------------------------------
771 // Callbacks (now obsolete - use events instead)
772 // --------------------------------------------------------------------------
774 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
776 wxSockCbk old_cbk
= cbk_
;
782 char *wxSocketBase::CallbackData(char *data
)
784 char *old_data
= m_cdata
;
790 // --------------------------------------------------------------------------
792 // --------------------------------------------------------------------------
794 // All events (INPUT, OUTPUT, CONNECTION, LOST) are now always
795 // internally watched; but users will only be notified of those
796 // events they are interested in.
798 static void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
802 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
804 sckobj
->OnRequest((wxSocketNotify
)event
);
807 wxSocketEventFlags
wxSocketBase::EventToNotify(wxSocketNotify evt
)
811 case GSOCK_INPUT
: return GSOCK_INPUT_FLAG
;
812 case GSOCK_OUTPUT
: return GSOCK_OUTPUT_FLAG
;
813 case GSOCK_CONNECTION
: return GSOCK_CONNECTION_FLAG
;
814 case GSOCK_LOST
: return GSOCK_LOST_FLAG
;
819 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
824 void wxSocketBase::Notify(bool notify
)
826 m_notify_state
= notify
;
829 void wxSocketBase::OnRequest(wxSocketNotify req_evt
)
831 wxSocketEvent
event(m_id
);
832 wxSocketEventFlags flag
= EventToNotify(req_evt
);
834 // This duplicates some code in _Wait, but this doesn't
835 // hurt. It has to be here because we don't know whether
836 // the Wait functions will be used, and it has to be in
837 // _Wait as well because the event might be a bit delayed.
841 case wxSOCKET_CONNECTION
:
842 m_establishing
= FALSE
;
846 // If we are in the middle of a R/W operation, do not
847 // propagate events to users. Also, filter 'late' events
848 // which are no longer valid.
851 if (m_reading
|| !GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
855 case wxSOCKET_OUTPUT
:
856 if (m_writing
|| !GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
))
862 m_establishing
= FALSE
;
869 if (((m_neededreq
& flag
) == flag
) && m_notify_state
)
871 event
.m_socket
= this;
872 event
.m_skevt
= req_evt
;
875 #if USE_DELAYED_EVENTS
876 wxPostEvent(m_evt_handler
, event
);
881 OldOnNotify(req_evt
);
883 m_cbk(*this, req_evt
, m_cdata
);
887 void wxSocketBase::OldOnNotify(wxSocketNotify
WXUNUSED(evt
))
891 void wxSocketBase::SetEventHandler(wxEvtHandler
& h_evt
, int id
)
893 m_evt_handler
= &h_evt
;
896 SetNextHandler(&h_evt
);
899 // --------------------------------------------------------------------------
901 // --------------------------------------------------------------------------
903 void wxSocketBase::Pushback(const char *buffer
, wxUint32 size
)
907 if (m_unread
== NULL
)
908 m_unread
= (char *)malloc(size
);
913 tmp
= (char *)malloc(m_unrd_size
+ size
);
914 memcpy(tmp
+size
, m_unread
, m_unrd_size
);
922 memcpy(m_unread
, buffer
, size
);
925 wxUint32
wxSocketBase::GetPushback(char *buffer
, wxUint32 size
, bool peek
)
930 if (size
> (m_unrd_size
-m_unrd_cur
))
931 size
= m_unrd_size
-m_unrd_cur
;
933 memcpy(buffer
, (m_unread
+m_unrd_cur
), size
);
938 if (m_unrd_size
== m_unrd_cur
)
950 // ==========================================================================
952 // ==========================================================================
954 // --------------------------------------------------------------------------
956 // --------------------------------------------------------------------------
958 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
960 : wxSocketBase(flags
, SOCK_SERVER
)
963 m_socket
= GSocket_new();
968 // Setup the socket as server
969 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
970 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
972 GSocket_destroy(m_socket
);
977 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
978 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
979 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
980 wx_socket_callback
, (char *)this);
984 // --------------------------------------------------------------------------
986 // --------------------------------------------------------------------------
988 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
990 GSocket
*child_socket
;
995 // If wait == FALSE, then the call should be nonblocking.
996 // When we are finished, we put the socket to blocking mode
1000 GSocket_SetNonBlocking(m_socket
, TRUE
);
1002 child_socket
= GSocket_WaitConnection(m_socket
);
1005 GSocket_SetNonBlocking(m_socket
, FALSE
);
1010 sock
.m_type
= SOCK_INTERNAL
;
1011 sock
.m_socket
= child_socket
;
1012 sock
.m_connected
= TRUE
;
1014 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
* 1000);
1015 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1016 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1017 wx_socket_callback
, (char *)&sock
);
1022 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1024 wxSocketBase
* sock
= new wxSocketBase();
1026 sock
->SetFlags((wxSockFlags
)m_flags
);
1028 if (!AcceptWith(*sock
, wait
))
1034 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1036 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1039 // ==========================================================================
1041 // ==========================================================================
1043 // --------------------------------------------------------------------------
1045 // --------------------------------------------------------------------------
1047 wxSocketClient::wxSocketClient(wxSockFlags _flags
)
1048 : wxSocketBase(_flags
, SOCK_CLIENT
)
1052 // XXX: What is this for ?
1053 wxSocketClient::~wxSocketClient()
1057 // --------------------------------------------------------------------------
1059 // --------------------------------------------------------------------------
1061 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1067 // Shutdown and destroy the socket
1069 GSocket_destroy(m_socket
);
1072 m_socket
= GSocket_new();
1073 m_connected
= FALSE
;
1074 m_establishing
= FALSE
;
1079 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1080 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1081 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1082 wx_socket_callback
, (char *)this);
1084 // If wait == FALSE, then the call should be nonblocking.
1085 // When we are finished, we put the socket to blocking mode
1089 GSocket_SetNonBlocking(m_socket
, TRUE
);
1091 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1092 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1095 GSocket_SetNonBlocking(m_socket
, FALSE
);
1097 if (err
!= GSOCK_NOERROR
)
1099 if (err
== GSOCK_WOULDBLOCK
)
1100 m_establishing
= TRUE
;
1109 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1111 if (m_connected
) // Already connected
1114 if (!m_establishing
|| !m_socket
) // No connection in progress
1117 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1120 // ==========================================================================
1122 // ==========================================================================
1124 /* NOTE: experimental stuff - might change */
1126 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
, wxSockFlags flags
)
1127 : wxSocketBase( flags
, SOCK_DATAGRAM
)
1129 // Create the socket
1130 m_socket
= GSocket_new();
1135 // Setup the socket as non connection oriented
1136 GSocket_SetLocal(m_socket
, addr
.GetAddress());
1137 if( GSocket_SetNonOriented(m_socket
) != GSOCK_NOERROR
)
1139 GSocket_destroy(m_socket
);
1144 // Initialize all stuff
1145 m_connected
= FALSE
;
1146 m_establishing
= FALSE
;
1147 GSocket_SetTimeout( m_socket
, m_timeout
);
1148 GSocket_SetCallback( m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1149 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1150 wx_socket_callback
, (char*)this );
1154 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1163 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1167 GSocket_SetPeer(m_socket
, addr
.GetAddress());
1172 // ==========================================================================
1174 // ==========================================================================
1176 // XXX: Should be moved to event.cpp ?
1178 wxSocketEvent::wxSocketEvent(int id
)
1181 wxEventType type
= (wxEventType
)wxEVT_SOCKET
;
1186 void wxSocketEvent::CopyObject(wxObject
& obj_d
) const
1188 wxSocketEvent
*event
= (wxSocketEvent
*)&obj_d
;
1190 wxEvent::CopyObject(obj_d
);
1192 event
->m_skevt
= m_skevt
;
1193 event
->m_socket
= m_socket
;
1196 // ==========================================================================
1198 // ==========================================================================
1200 class WXDLLEXPORT wxSocketModule
: public wxModule
1202 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1205 bool OnInit() { return GSocket_Init(); }
1206 void OnExit() { GSocket_Cleanup(); }
1209 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)