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"
40 #include "wx/gdicmn.h" // for wxPendingDelete
43 #include "wx/sckaddr.h"
44 #include "wx/socket.h"
48 #define MAX_DISCARD_SIZE (10 * 1024)
50 // what to do within waits
51 #define PROCESS_EVENTS() wxYield()
53 // use wxPostEvent or not
54 #define USE_DELAYED_EVENTS 1
56 // --------------------------------------------------------------------------
58 // --------------------------------------------------------------------------
60 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
61 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
62 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
63 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
64 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
66 class wxSocketState
: public wxObject
70 wxSocketEventFlags m_neededreq
;
72 wxSocketBase::wxSockCbk m_cbk
;
76 wxSocketState() : wxObject() {}
80 // ==========================================================================
82 // ==========================================================================
84 // --------------------------------------------------------------------------
86 // --------------------------------------------------------------------------
88 wxSocketBase::wxSocketBase(wxSockFlags _flags
, wxSockType _type
) :
90 m_socket(NULL
), m_evt_handler(NULL
), m_id(-1),
91 m_flags(_flags
), m_type(_type
),
92 m_neededreq(0), m_notify_state(FALSE
),
93 m_connected(FALSE
), m_establishing(FALSE
),
94 m_reading(FALSE
), m_writing(FALSE
),
95 m_error(FALSE
), m_lcount(0), m_timeout(600),
96 m_states(), m_beingDeleted(FALSE
),
97 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
98 m_cbk(NULL
), m_cdata(NULL
)
102 wxSocketBase::wxSocketBase() :
104 m_socket(NULL
), m_evt_handler(NULL
), m_id(-1),
105 m_flags(NONE
), m_type(SOCK_UNINIT
),
106 m_neededreq(0), m_notify_state(FALSE
),
107 m_connected(FALSE
), m_establishing(FALSE
),
108 m_reading(FALSE
), m_writing(FALSE
),
109 m_error(FALSE
), m_lcount(0), m_timeout(600),
110 m_states(), m_beingDeleted(FALSE
),
111 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
112 m_cbk(NULL
), m_cdata(NULL
)
116 wxSocketBase::~wxSocketBase()
118 // Just in case the app called Destroy() *and* then deleted
119 // the socket immediately: don't leave dangling pointers.
121 wxPendingDelete
.DeleteObject(this);
124 // Shutdown and close the socket
128 // Destroy the GSocket object
130 GSocket_destroy(m_socket
);
132 // Free the pushback buffer
137 bool wxSocketBase::Destroy()
139 // Delayed destruction: the socket will be deleted during the next
140 // idle loop iteration. This ensures that all pending events have
142 m_beingDeleted
= TRUE
;
144 // Shutdown and close the socket
148 if ( wxPendingDelete
.Member(this) )
149 wxPendingDelete
.Append(this);
158 // --------------------------------------------------------------------------
159 // Basic IO operations
160 // --------------------------------------------------------------------------
162 // The following IO operations update m_error and m_lcount:
163 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
165 // TODO: Should Connect, Accept and AcceptWith update m_error?
167 bool wxSocketBase::Close()
169 // Interrupt pending waits
175 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
176 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
178 // Shutdown the connection
179 GSocket_Shutdown(m_socket
);
183 m_establishing
= FALSE
;
187 wxSocketBase
& wxSocketBase::Read(char* buffer
, wxUint32 nbytes
)
192 m_lcount
= _Read(buffer
, nbytes
);
194 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
195 if (m_flags
& wxSOCKET_WAITALL
)
196 m_error
= (m_lcount
!= nbytes
);
198 m_error
= (m_lcount
== 0);
200 // Allow read events from now on
206 wxUint32
wxSocketBase::_Read(char* buffer
, wxUint32 nbytes
)
211 // Try the pushback buffer first
212 total
= GetPushback(buffer
, nbytes
, FALSE
);
216 // If the socket is invalid or we got all the data, return now
217 if (!m_socket
|| !nbytes
)
220 // Possible combinations (they are checked in this order)
222 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
227 if (m_flags
& wxSOCKET_NOWAIT
)
229 GSocket_SetNonBlocking(m_socket
, TRUE
);
230 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
231 GSocket_SetNonBlocking(m_socket
, FALSE
);
236 else if (m_flags
& wxSOCKET_WAITALL
)
238 while (ret
> 0 && nbytes
> 0)
240 if (!(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead())
243 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
255 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForRead())
257 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
267 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, wxUint32 nbytes
)
269 wxUint32 len
, len2
, sig
, total
;
274 unsigned char sig
[4];
275 unsigned char len
[4];
284 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
286 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
289 sig
= (wxUint32
)msg
.sig
[0];
290 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
291 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
292 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
294 if (sig
!= 0xfeeddead)
296 wxLogWarning( _("wxSocket: invalid signature in ReadMsg."));
300 len
= (wxUint32
)msg
.len
[0];
301 len
|= (wxUint32
)(msg
.len
[1] << 8);
302 len
|= (wxUint32
)(msg
.len
[2] << 16);
303 len
|= (wxUint32
)(msg
.len
[3] << 24);
313 // Don't attemp to read if the msg was zero bytes long.
316 total
= _Read(buffer
, len
);
323 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
326 // NOTE: discarded bytes don't add to m_lcount.
329 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
330 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
331 len2
-= (wxUint32
)discard_len
;
333 while ((discard_len
> 0) && len2
);
335 delete [] discard_buffer
;
340 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
343 sig
= (wxUint32
)msg
.sig
[0];
344 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
345 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
346 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
348 if (sig
!= 0xdeadfeed)
350 wxLogWarning( _("wxSocket: invalid signature in ReadMsg."));
366 wxSocketBase
& wxSocketBase::Peek(char* buffer
, wxUint32 nbytes
)
371 m_lcount
= _Read(buffer
, nbytes
);
372 Pushback(buffer
, m_lcount
);
374 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
375 if (m_flags
& wxSOCKET_WAITALL
)
376 m_error
= (m_lcount
!= nbytes
);
378 m_error
= (m_lcount
== 0);
380 // Allow read events again
386 wxSocketBase
& wxSocketBase::Write(const char *buffer
, wxUint32 nbytes
)
391 m_lcount
= _Write(buffer
, nbytes
);
393 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
394 if (m_flags
& wxSOCKET_WAITALL
)
395 m_error
= (m_lcount
!= nbytes
);
397 m_error
= (m_lcount
== 0);
399 // Allow write events again
405 wxUint32
wxSocketBase::_Write(const char *buffer
, wxUint32 nbytes
)
410 // If the socket is invalid, return immediately
414 // Possible combinations (they are checked in this order)
416 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
421 if (m_flags
& wxSOCKET_NOWAIT
)
423 GSocket_SetNonBlocking(m_socket
, TRUE
);
424 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
425 GSocket_SetNonBlocking(m_socket
, FALSE
);
430 else if (m_flags
& wxSOCKET_WAITALL
)
432 while (ret
> 0 && nbytes
> 0)
434 if (!(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite())
437 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
449 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForWrite())
451 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
461 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, wxUint32 nbytes
)
467 unsigned char sig
[4];
468 unsigned char len
[4];
477 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
479 msg
.sig
[0] = (unsigned char) 0xad;
480 msg
.sig
[1] = (unsigned char) 0xde;
481 msg
.sig
[2] = (unsigned char) 0xed;
482 msg
.sig
[3] = (unsigned char) 0xfe;
484 msg
.len
[0] = (unsigned char) (nbytes
& 0xff);
485 msg
.len
[1] = (unsigned char) ((nbytes
>> 8) & 0xff);
486 msg
.len
[2] = (unsigned char) ((nbytes
>> 16) & 0xff);
487 msg
.len
[3] = (unsigned char) ((nbytes
>> 24) & 0xff);
489 if (_Write((char *)&msg
, sizeof(msg
)) < sizeof(msg
))
492 total
= _Write(buffer
, nbytes
);
497 msg
.sig
[0] = (unsigned char) 0xed;
498 msg
.sig
[1] = (unsigned char) 0xfe;
499 msg
.sig
[2] = (unsigned char) 0xad;
500 msg
.sig
[3] = (unsigned char) 0xde;
501 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
503 if ((_Write((char *)&msg
, sizeof(msg
))) < sizeof(msg
))
517 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, wxUint32 nbytes
)
520 Pushback(buffer
, nbytes
);
528 wxSocketBase
& wxSocketBase::Discard()
531 char *buffer
= new char[MAX_DISCARD_SIZE
];
539 SetFlags(wxSOCKET_NOWAIT
);
543 ret
= _Read(buffer
, MAX_DISCARD_SIZE
);
546 while (ret
== MAX_DISCARD_SIZE
);
552 // Allow read events again
558 // --------------------------------------------------------------------------
560 // --------------------------------------------------------------------------
562 // All Wait functions poll the socket using GSocket_Select() to
563 // check for the specified combination of conditions, until one
564 // of these conditions become true, an error occurs, or the
565 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
566 // this won't block the GUI.
570 class _wxSocketInternalTimer
: public wxTimer
574 unsigned long m_new_val
;
578 *m_state
= (int)m_new_val
; // Change the value
584 bool wxSocketBase::_Wait(long seconds
, long milliseconds
,
585 wxSocketEventFlags flags
)
587 GSocketEventFlags result
;
589 _wxSocketInternalTimer timer
;
590 wxTimerRunner
runTimer(timer
);
596 // Set this to TRUE to interrupt ongoing waits
599 // Check for valid socket
603 // Check for valid timeout value
605 timeout
= seconds
* 1000 + milliseconds
;
607 timeout
= m_timeout
* 1000;
613 timer
.m_state
= &state
;
615 runTimer
.Start((int)timeout
, TRUE
);
619 // Active polling (without using events)
621 // NOTE: this duplicates some of the code in OnRequest (lost
622 // connection and connection establishment handling) but
623 // this doesn't hurt. It has to be here because the event
624 // might be a bit delayed, and it has to be in OnRequest
625 // as well because maybe the Wait functions are not being
628 // Do this at least once (important if timeout == 0, when
629 // we are just polling). Also, if just polling, do not yield.
633 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
635 // Incoming connection (server) or connection established (client)
636 if (result
& GSOCK_CONNECTION_FLAG
)
639 m_establishing
= FALSE
;
643 // Data available or output buffer ready
644 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
650 if (result
& GSOCK_LOST_FLAG
)
653 m_establishing
= FALSE
;
654 return (flags
& GSOCK_LOST_FLAG
);
658 if ((timeout
== 0) || (m_interrupt
))
667 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
669 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
671 GSOCK_CONNECTION_FLAG
|
675 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
677 // Check pushback buffer before entering _Wait
681 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
682 // _Wait becuase of the semantics of WaitForRead: a return
683 // value of TRUE means that a GSocket_Read call will return
684 // immediately, not that there is actually data to read.
686 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
690 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
692 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
695 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
697 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
700 // --------------------------------------------------------------------------
702 // --------------------------------------------------------------------------
705 // Get local or peer address
708 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
715 peer
= GSocket_GetPeer(m_socket
);
716 addr_man
.SetAddress(peer
);
717 GAddress_destroy(peer
);
722 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
729 local
= GSocket_GetLocal(m_socket
);
730 addr_man
.SetAddress(local
);
731 GAddress_destroy(local
);
737 // Save and restore socket state
740 void wxSocketBase::SaveState()
742 wxSocketState
*state
;
744 state
= new wxSocketState();
746 state
->m_notify_state
= m_notify_state
;
747 state
->m_neededreq
= m_neededreq
;
748 state
->m_flags
= m_flags
;
749 state
->m_cbk
= m_cbk
;
750 state
->m_cdata
= m_cdata
;
752 m_states
.Append(state
);
755 void wxSocketBase::RestoreState()
758 wxSocketState
*state
;
760 node
= m_states
.Last();
764 state
= (wxSocketState
*)node
->Data();
766 SetFlags(state
->m_flags
);
767 m_cbk
= state
->m_cbk
;
768 m_cdata
= state
->m_cdata
;
769 m_neededreq
= state
->m_neededreq
;
770 Notify(state
->m_notify_state
);
780 void wxSocketBase::SetTimeout(long seconds
)
785 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
788 void wxSocketBase::SetFlags(wxSockFlags _flags
)
793 // --------------------------------------------------------------------------
794 // Callbacks (now obsolete - use events instead)
795 // --------------------------------------------------------------------------
797 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
799 wxSockCbk old_cbk
= cbk_
;
805 char *wxSocketBase::CallbackData(char *data
)
807 char *old_data
= m_cdata
;
813 // --------------------------------------------------------------------------
815 // --------------------------------------------------------------------------
817 // All events (INPUT, OUTPUT, CONNECTION, LOST) are now always
818 // internally watched; but users will only be notified of those
819 // events they are interested in.
821 static void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
825 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
827 sckobj
->OnRequest((wxSocketNotify
)event
);
830 wxSocketEventFlags
wxSocketBase::EventToNotify(wxSocketNotify evt
)
834 case GSOCK_INPUT
: return GSOCK_INPUT_FLAG
;
835 case GSOCK_OUTPUT
: return GSOCK_OUTPUT_FLAG
;
836 case GSOCK_CONNECTION
: return GSOCK_CONNECTION_FLAG
;
837 case GSOCK_LOST
: return GSOCK_LOST_FLAG
;
842 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
847 void wxSocketBase::Notify(bool notify
)
849 m_notify_state
= notify
;
852 void wxSocketBase::OnRequest(wxSocketNotify req_evt
)
854 wxSocketEvent
event(m_id
);
855 wxSocketEventFlags flag
= EventToNotify(req_evt
);
857 // This duplicates some code in _Wait, but this doesn't
858 // hurt. It has to be here because we don't know whether
859 // the Wait functions will be used, and it has to be in
860 // _Wait as well because the event might be a bit delayed.
864 case wxSOCKET_CONNECTION
:
865 m_establishing
= FALSE
;
869 // If we are in the middle of a R/W operation, do not
870 // propagate events to users. Also, filter 'late' events
871 // which are no longer valid.
874 if (m_reading
|| !GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
878 case wxSOCKET_OUTPUT
:
879 if (m_writing
|| !GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
))
885 m_establishing
= FALSE
;
892 if (((m_neededreq
& flag
) == flag
) && m_notify_state
)
894 event
.m_socket
= this;
895 event
.m_skevt
= req_evt
;
899 #if USE_DELAYED_EVENTS
900 wxPostEvent(m_evt_handler
, event
);
906 OldOnNotify(req_evt
);
908 m_cbk(*this, req_evt
, m_cdata
);
912 void wxSocketBase::OldOnNotify(wxSocketNotify
WXUNUSED(evt
))
916 void wxSocketBase::SetEventHandler(wxEvtHandler
& h_evt
, int id
)
918 m_evt_handler
= &h_evt
;
921 SetNextHandler(&h_evt
);
924 // --------------------------------------------------------------------------
926 // --------------------------------------------------------------------------
928 void wxSocketBase::Pushback(const char *buffer
, wxUint32 size
)
932 if (m_unread
== NULL
)
933 m_unread
= (char *)malloc(size
);
938 tmp
= (char *)malloc(m_unrd_size
+ size
);
939 memcpy(tmp
+size
, m_unread
, m_unrd_size
);
947 memcpy(m_unread
, buffer
, size
);
950 wxUint32
wxSocketBase::GetPushback(char *buffer
, wxUint32 size
, bool peek
)
955 if (size
> (m_unrd_size
-m_unrd_cur
))
956 size
= m_unrd_size
-m_unrd_cur
;
958 memcpy(buffer
, (m_unread
+m_unrd_cur
), size
);
963 if (m_unrd_size
== m_unrd_cur
)
975 // ==========================================================================
977 // ==========================================================================
979 // --------------------------------------------------------------------------
981 // --------------------------------------------------------------------------
983 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
985 : wxSocketBase(flags
, SOCK_SERVER
)
988 m_socket
= GSocket_new();
993 // Setup the socket as server
994 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
995 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
997 GSocket_destroy(m_socket
);
1002 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1003 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1004 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1005 wx_socket_callback
, (char *)this);
1009 // --------------------------------------------------------------------------
1011 // --------------------------------------------------------------------------
1013 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1015 GSocket
*child_socket
;
1020 // If wait == FALSE, then the call should be nonblocking.
1021 // When we are finished, we put the socket to blocking mode
1025 GSocket_SetNonBlocking(m_socket
, TRUE
);
1027 child_socket
= GSocket_WaitConnection(m_socket
);
1030 GSocket_SetNonBlocking(m_socket
, FALSE
);
1035 sock
.m_type
= SOCK_INTERNAL
;
1036 sock
.m_socket
= child_socket
;
1037 sock
.m_connected
= TRUE
;
1039 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
* 1000);
1040 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1041 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1042 wx_socket_callback
, (char *)&sock
);
1047 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1049 wxSocketBase
* sock
= new wxSocketBase();
1051 sock
->SetFlags((wxSockFlags
)m_flags
);
1053 if (!AcceptWith(*sock
, wait
))
1059 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1061 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1064 // ==========================================================================
1066 // ==========================================================================
1068 // --------------------------------------------------------------------------
1070 // --------------------------------------------------------------------------
1072 wxSocketClient::wxSocketClient(wxSockFlags _flags
)
1073 : wxSocketBase(_flags
, SOCK_CLIENT
)
1077 // XXX: What is this for ?
1078 wxSocketClient::~wxSocketClient()
1082 // --------------------------------------------------------------------------
1084 // --------------------------------------------------------------------------
1086 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1092 // Shutdown and destroy the socket
1094 GSocket_destroy(m_socket
);
1097 m_socket
= GSocket_new();
1098 m_connected
= FALSE
;
1099 m_establishing
= FALSE
;
1104 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1105 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1106 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1107 wx_socket_callback
, (char *)this);
1109 // If wait == FALSE, then the call should be nonblocking.
1110 // When we are finished, we put the socket to blocking mode
1114 GSocket_SetNonBlocking(m_socket
, TRUE
);
1116 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1117 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1120 GSocket_SetNonBlocking(m_socket
, FALSE
);
1122 if (err
!= GSOCK_NOERROR
)
1124 if (err
== GSOCK_WOULDBLOCK
)
1125 m_establishing
= TRUE
;
1134 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1136 if (m_connected
) // Already connected
1139 if (!m_establishing
|| !m_socket
) // No connection in progress
1142 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1145 // ==========================================================================
1147 // ==========================================================================
1149 /* NOTE: experimental stuff - might change */
1151 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
, wxSockFlags flags
)
1152 : wxSocketBase( flags
, SOCK_DATAGRAM
)
1154 // Create the socket
1155 m_socket
= GSocket_new();
1160 // Setup the socket as non connection oriented
1161 GSocket_SetLocal(m_socket
, addr
.GetAddress());
1162 if( GSocket_SetNonOriented(m_socket
) != GSOCK_NOERROR
)
1164 GSocket_destroy(m_socket
);
1169 // Initialize all stuff
1170 m_connected
= FALSE
;
1171 m_establishing
= FALSE
;
1172 GSocket_SetTimeout( m_socket
, m_timeout
);
1173 GSocket_SetCallback( m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1174 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1175 wx_socket_callback
, (char*)this );
1179 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1188 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1192 GSocket_SetPeer(m_socket
, addr
.GetAddress());
1197 // ==========================================================================
1199 // ==========================================================================
1201 // XXX: Should be moved to event.cpp ?
1203 wxSocketEvent::wxSocketEvent(int id
)
1206 wxEventType type
= (wxEventType
)wxEVT_SOCKET
;
1211 void wxSocketEvent::CopyObject(wxObject
& obj_d
) const
1213 wxSocketEvent
*event
= (wxSocketEvent
*)&obj_d
;
1215 wxEvent::CopyObject(obj_d
);
1217 event
->m_skevt
= m_skevt
;
1218 event
->m_socket
= m_socket
;
1221 // ==========================================================================
1223 // ==========================================================================
1225 class WXDLLEXPORT wxSocketModule
: public wxModule
1227 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1230 bool OnInit() { return GSocket_Init(); }
1231 void OnExit() { GSocket_Cleanup(); }
1234 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)