1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
7 // Copyright: (C) 1999, 1998, 1997, Guilhem Lavaux
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 /////////////////////////////////////////////////////////////////////////////
27 /////////////////////////////////////////////////////////////////////////////
29 #include "wx/object.h"
30 #include "wx/string.h"
33 #include "wx/module.h"
40 /////////////////////////////////////////////////////////////////////////////
42 /////////////////////////////////////////////////////////////////////////////
43 #include "wx/sckaddr.h"
44 #include "wx/socket.h"
46 // --------------------------------------------------------------
48 // --------------------------------------------------------------
49 #if !USE_SHARED_LIBRARY
50 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
51 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
52 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
53 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
56 class wxSocketState
: public wxObject
60 GSocketEventFlags evt_notify_state
;
61 wxSocketBase::wxSockFlags socket_flags
;
62 wxSocketBase::wxSockCbk c_callback
;
63 char *c_callback_data
;
66 wxSocketState() : wxObject() {}
69 // --------------------------------------------------------------
70 // wxSocketBase ctor and dtor
71 // --------------------------------------------------------------
73 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags
,
74 wxSocketBase::wxSockType _type
) :
76 m_socket(NULL
), m_flags(_flags
), m_type(_type
),
78 m_lcount(0), m_timeout(600),
79 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
80 m_cbk(NULL
), m_cdata(NULL
),
81 m_connected(FALSE
), m_establishing(FALSE
),
82 m_notify_state(FALSE
), m_id(-1),
83 m_defering(NO_DEFER
), m_error(FALSE
),
88 wxSocketBase::wxSocketBase() :
90 m_socket(NULL
), m_flags(WAITALL
| SPEED
), m_type(SOCK_UNINIT
),
92 m_lcount(0), m_timeout(600),
93 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
94 m_cbk(NULL
), m_cdata(NULL
),
95 m_connected(FALSE
), m_establishing(FALSE
),
96 m_notify_state(FALSE
), m_id(-1),
97 m_defering(NO_DEFER
), m_error(FALSE
),
102 wxSocketBase::~wxSocketBase()
107 // Shutdown and close the socket
110 // Destroy the GSocket object
112 GSocket_destroy(m_socket
);
115 bool wxSocketBase::Close()
120 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
121 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
123 // Shutdown the connection
124 GSocket_Shutdown(m_socket
);
126 m_establishing
= FALSE
;
132 // --------------------------------------------------------------
133 // wxSocketBase basic IO operations
134 // --------------------------------------------------------------
136 // GRG: I have made some changes to wxSocket internal event
137 // system; now, all events (INPUT, OUTPUT, CONNECTION, LOST)
138 // are always internally monitored; but users will only be
139 // notified of these events they are interested in. So we
140 // no longer have to change the event mask with SetNotify()
141 // in internal functions like DeferRead, DeferWrite, and
142 // the like. This solves a lot of problems.
144 // GRG: I added m_error handling to IO operations. Now,
145 // wxSocketBase::Error() correctly indicates if the last
146 // operation from {Read, Write, ReadMsg, WriteMsg, Peek,
147 // Unread, Discard} failed. Note that now, every function
148 // that updates m_lcount, also updates m_error. While I
149 // was at it, also fixed an UGLY bug in ReadMsg.
151 class _wxSocketInternalTimer
: public wxTimer
155 unsigned long m_new_val
;
159 *m_state
= m_new_val
; // Change the value
163 int wxSocketBase::DeferRead(char *buffer
, wxUint32 nbytes
)
166 _wxSocketInternalTimer timer
;
168 wxASSERT(m_defering
== NO_DEFER
);
170 // Set the defering mode to READ.
171 m_defering
= DEFER_READ
;
173 // Set the current buffer.
174 m_defer_buffer
= buffer
;
175 m_defer_nbytes
= nbytes
;
176 m_defer_timer
= &timer
;
178 timer
.m_state
= (int *)&m_defer_buffer
;
181 timer
.Start(m_timeout
* 1000, FALSE
);
183 // If the socket is readable, call DoDefer for the first time
184 if (GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
187 // Wait for buffer completion.
188 while (m_defer_buffer
!= NULL
)
193 // Disable defering mode.
194 m_defering
= NO_DEFER
;
195 m_defer_timer
= NULL
;
197 // Return the number of bytes read from the socket.
198 return nbytes
-m_defer_nbytes
;
201 wxSocketBase
& wxSocketBase::Read(char* buffer
, wxUint32 nbytes
)
207 // we try this even if the connection has already been closed.
208 m_lcount
= GetPushback(buffer
, nbytes
, FALSE
);
212 if (!m_connected
|| !m_socket
)
214 // if no data retrieved AND not connected, it is an error.
221 // If we have got the whole needed buffer, return immediately
227 if (m_flags
& SPEED
& WAITALL
) // SPEED && WAITALL
229 while (ret
> 0 && nbytes
> 0)
231 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
236 // In case the last call was an error ...
240 else if (m_flags
& SPEED
) // SPEED && !WAITALL
242 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
249 ret
= DeferRead(buffer
, nbytes
);
255 // If we have read some data, then it is not an error, even
256 // when in WAITALL mode, the last low-level IO call might
264 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, wxUint32 nbytes
)
266 #define MAX_BUFSIZE (10 * 1024)
269 unsigned long len
, len2
, sig
;
276 // sig should be an explicit 32-bit unsigned integer; I've seen
277 // compilers in which wxUint32 was actually a 16-bit unsigned integer
280 SetFlags(WAITALL
| SPEED
);
282 Read((char *)&msg
, sizeof(msg
));
283 if (m_lcount
!= sizeof(msg
))
290 sig
= msg
.sig
[0] & 0xff;
291 sig
|= (wxUint32
)(msg
.sig
[1] & 0xff) << 8;
292 sig
|= (wxUint32
)(msg
.sig
[2] & 0xff) << 16;
293 sig
|= (wxUint32
)(msg
.sig
[3] & 0xff) << 24;
295 if (sig
!= 0xfeeddead)
297 wxLogDebug(_T("Warning: invalid signature returned to ReadMsg\n"));
303 len
= msg
.len
[0] & 0xff;
304 len
|= (wxUint32
)(msg
.len
[1] & 0xff) << 8;
305 len
|= (wxUint32
)(msg
.len
[2] & 0xff) << 16;
306 len
|= (wxUint32
)(msg
.len
[3] & 0xff) << 24;
316 // The "len &&" in the following statements is necessary so
317 // that we don't attempt to read (and possibly hang the system)
318 // if the message was zero bytes long
319 if (len
&& Read(buffer
, len
).LastCount() != len
)
327 char *discard_buffer
= new char[MAX_BUFSIZE
];
332 discard_len
= ((len2
> MAX_BUFSIZE
)? MAX_BUFSIZE
: len2
);
333 discard_len
= Read(discard_buffer
, discard_len
).LastCount();
336 while ((discard_len
> 0) && len2
);
338 delete [] discard_buffer
;
347 if (Read((char *)&msg
, sizeof(msg
)).LastCount() != sizeof(msg
))
354 sig
= msg
.sig
[0] & 0xff;
355 sig
|= (wxUint32
)(msg
.sig
[1] & 0xff) << 8;
356 sig
|= (wxUint32
)(msg
.sig
[2] & 0xff) << 16;
357 sig
|= (wxUint32
)(msg
.sig
[3] & 0xff) << 24;
359 if (sig
!= 0xdeadfeed)
362 wxLogDebug(_T("Warning: invalid signature returned to ReadMsg\n"));
371 wxSocketBase
& wxSocketBase::Peek(char* buffer
, wxUint32 nbytes
)
373 Read(buffer
, nbytes
);
374 CreatePushbackAfter(buffer
, nbytes
);
379 int wxSocketBase::DeferWrite(const char *buffer
, wxUint32 nbytes
)
382 _wxSocketInternalTimer timer
;
384 wxASSERT(m_defering
== NO_DEFER
);
386 m_defering
= DEFER_WRITE
;
388 // Set the current buffer
389 m_defer_buffer
= (char *)buffer
;
390 m_defer_nbytes
= nbytes
;
391 m_defer_timer
= &timer
;
394 timer
.m_state
= (int *)&m_defer_buffer
;
397 timer
.Start(m_timeout
* 1000, FALSE
);
399 // If the socket is writable, call DoDefer for the first time
400 if (GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
))
403 // Wait for buffer completion.
404 while (m_defer_buffer
!= NULL
)
408 m_defer_timer
= NULL
;
411 m_defering
= NO_DEFER
;
413 return nbytes
-m_defer_nbytes
;
416 wxSocketBase
& wxSocketBase::Write(const char *buffer
, wxUint32 nbytes
)
423 if (!m_connected
|| !m_socket
)
429 if (m_flags
& SPEED
& WAITALL
) // SPEED && WAITALL
431 while (ret
> 0 && nbytes
> 0)
433 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
438 // In case the last call was an error ...
442 else if (m_flags
& SPEED
) // SPEED && !WAITALL
444 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
451 ret
= DeferWrite(buffer
, nbytes
);
457 // If we have written some data, then it is not an error,
458 // even when in WAITALL mode, the last low-level IO call
459 // might have failed.
466 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, wxUint32 nbytes
)
474 // warning about 'cast truncates constant value'
476 #pragma warning(disable: 4310)
477 #endif // __VISUALC__
479 msg
.sig
[0] = (char) 0xad;
480 msg
.sig
[1] = (char) 0xde;
481 msg
.sig
[2] = (char) 0xed;
482 msg
.sig
[3] = (char) 0xfe;
484 msg
.len
[0] = (char) nbytes
& 0xff;
485 msg
.len
[1] = (char) (nbytes
>> 8) & 0xff;
486 msg
.len
[2] = (char) (nbytes
>> 16) & 0xff;
487 msg
.len
[3] = (char) (nbytes
>> 24) & 0xff;
489 // GRG: We need WAITALL | SPEED
491 SetFlags(WAITALL
| SPEED
);
493 if (Write((char *)&msg
, sizeof(msg
)).LastCount() < sizeof(msg
))
499 if (Write(buffer
, nbytes
).LastCount() < nbytes
)
506 msg
.sig
[0] = (char) 0xed;
507 msg
.sig
[1] = (char) 0xfe;
508 msg
.sig
[2] = (char) 0xad;
509 msg
.sig
[3] = (char) 0xde;
510 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
512 if (Write((char *)&msg
, sizeof(msg
)).LastCount() < sizeof(msg
))
519 #pragma warning(default: 4310)
520 #endif // __VISUALC__
523 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, wxUint32 nbytes
)
530 CreatePushbackAfter(buffer
, nbytes
);
536 bool wxSocketBase::IsData() const
541 return (GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
));
544 // GRG: DoDefer() no longer needs to know which event occured,
545 // because this was only used to catch LOST events and set
546 // m_defer_buffer = NULL; this is done in OnRequest() now.
548 void wxSocketBase::DoDefer()
558 ret
= GSocket_Read(m_socket
, m_defer_buffer
, m_defer_nbytes
);
561 ret
= GSocket_Write(m_socket
, m_defer_buffer
, m_defer_nbytes
);
569 m_defer_nbytes
-= ret
;
571 // If we are waiting for all bytes to be acquired, keep the defering
573 if ((m_flags
& WAITALL
) == 0 || m_defer_nbytes
== 0 || ret
< 0)
575 m_defer_buffer
= NULL
;
579 m_defer_buffer
+= ret
;
580 m_defer_timer
->Start(m_timeout
* 1000, FALSE
);
584 void wxSocketBase::Discard()
586 #define MAX_BUFSIZE (10*1024)
588 char *my_data
= new char[MAX_BUFSIZE
];
589 wxUint32 recv_size
= MAX_BUFSIZE
;
593 SetFlags(NOWAIT
); // GRG: SPEED was not needed here!
595 while (recv_size
== MAX_BUFSIZE
)
597 recv_size
= Read(my_data
, MAX_BUFSIZE
).LastCount();
610 // --------------------------------------------------------------
611 // wxSocketBase get local or peer addresses
612 // --------------------------------------------------------------
614 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
621 peer
= GSocket_GetPeer(m_socket
);
622 addr_man
.SetAddress(peer
);
623 GAddress_destroy(peer
);
628 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
635 local
= GSocket_GetLocal(m_socket
);
636 addr_man
.SetAddress(local
);
637 GAddress_destroy(local
);
642 // --------------------------------------------------------------
643 // wxSocketBase save and restore socket state
644 // --------------------------------------------------------------
646 void wxSocketBase::SaveState()
648 wxSocketState
*state
;
650 state
= new wxSocketState();
652 state
->notify_state
= m_notify_state
;
653 state
->evt_notify_state
= m_neededreq
;
654 state
->socket_flags
= m_flags
;
655 state
->c_callback
= m_cbk
;
656 state
->c_callback_data
= m_cdata
;
658 m_states
.Append(state
);
661 void wxSocketBase::RestoreState()
664 wxSocketState
*state
;
666 node
= m_states
.Last();
670 state
= (wxSocketState
*)node
->Data();
672 SetFlags(state
->socket_flags
);
673 m_neededreq
= state
->evt_notify_state
;
674 m_cbk
= state
->c_callback
;
675 m_cdata
= state
->c_callback_data
;
676 Notify(state
->notify_state
);
683 // --------------------------------------------------------------
684 // wxSocketBase Wait functions
685 // --------------------------------------------------------------
687 // GRG: I have completely rewritten this family of functions
688 // so that they don't depend on event notifications; instead,
689 // they poll the socket, using GSocket_Select(), to check for
690 // the specified combination of event flags, until an event
691 // occurs or until the timeout ellapses. The polling loop
692 // calls wxYield(), so this won't block the GUI.
694 bool wxSocketBase::_Wait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
696 GSocketEventFlags result
;
697 _wxSocketInternalTimer timer
;
701 // Check for valid socket
702 if ((!m_connected
&& !m_establishing
) || !m_socket
)
705 // Check for valid timeout value
707 timeout
= seconds
* 1000 + milliseconds
;
709 timeout
= m_timeout
* 1000;
712 timer
.m_state
= &state
;
714 timer
.Start(timeout
, TRUE
);
716 // Active polling (without using events)
717 result
= GSocket_Select(m_socket
, flags
);
719 while ((result
== 0) && (state
== -1))
722 result
= GSocket_Select(m_socket
, flags
);
727 return (result
!= 0);
730 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
732 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
734 GSOCK_CONNECTION_FLAG
|
738 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
740 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
| GSOCK_LOST_FLAG
);
743 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
745 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
| GSOCK_LOST_FLAG
);
748 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
750 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
753 void wxSocketBase::SetTimeout(long seconds
)
758 GSocket_SetTimeout(m_socket
, m_timeout
);
761 // --------------------------------------------------------------
762 // wxSocketBase flags
763 // --------------------------------------------------------------
765 void wxSocketBase::SetFlags(wxSockFlags _flags
)
770 wxSocketBase::wxSockFlags
wxSocketBase::GetFlags() const
775 // --------------------------------------------------------------
776 // wxSocketBase callback management
777 // --------------------------------------------------------------
779 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
781 wxSockCbk old_cbk
= cbk_
;
787 char *wxSocketBase::CallbackData(char *data
)
789 char *old_data
= m_cdata
;
795 // --------------------------------------------------------------
796 // wxSocketBase automatic notifier
797 // --------------------------------------------------------------
799 static void LINKAGEMODE
wx_socket_callback(GSocket
*socket
, GSocketEvent event
, char *cdata
)
801 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
803 sckobj
->OnRequest((wxSocketNotify
)event
);
806 wxSocketEventFlags
wxSocketBase::EventToNotify(wxSocketNotify evt
)
810 case GSOCK_INPUT
: return GSOCK_INPUT_FLAG
;
811 case GSOCK_OUTPUT
: return GSOCK_OUTPUT_FLAG
;
812 case GSOCK_CONNECTION
: return GSOCK_CONNECTION_FLAG
;
813 case GSOCK_LOST
: return GSOCK_LOST_FLAG
;
818 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
823 void wxSocketBase::Notify(bool notify
)
825 m_notify_state
= notify
;
828 void wxSocketBase::OnRequest(wxSocketNotify req_evt
)
830 wxSocketEvent
event(m_id
);
831 wxSocketEventFlags flag
= EventToNotify(req_evt
);
835 case wxSOCKET_CONNECTION
:
836 m_establishing
= FALSE
;
840 m_defer_buffer
= NULL
;
844 case wxSOCKET_OUTPUT
:
847 // GRG: DoDefer() no longer needs to know which
848 // event occured, because this was only used to
849 // catch LOST events and set m_defer_buffer to
850 // NULL, and this is done in OnRequest() now.
852 // Do not notify to user
858 if (((m_neededreq
& flag
) == flag
) && m_notify_state
)
860 event
.m_socket
= this;
861 event
.m_skevt
= req_evt
;
863 OldOnNotify(req_evt
);
866 m_cbk(*this, req_evt
, m_cdata
);
870 void wxSocketBase::OldOnNotify(wxSocketNotify evt
)
874 // --------------------------------------------------------------
875 // wxSocketBase set event handler
876 // --------------------------------------------------------------
878 void wxSocketBase::SetEventHandler(wxEvtHandler
& h_evt
, int id
)
880 SetNextHandler(&h_evt
);
884 // --------------------------------------------------------------
885 // wxSocketBase pushback library
886 // --------------------------------------------------------------
888 void wxSocketBase::CreatePushbackAfter(const char *buffer
, wxUint32 size
)
892 if (m_unread
!= NULL
)
893 m_unread
= (char *) realloc(m_unread
, m_unrd_size
+size
);
895 m_unread
= (char *) malloc(size
);
897 curr_pos
= m_unread
+ m_unrd_size
;
899 memcpy(curr_pos
, buffer
, size
);
903 void wxSocketBase::CreatePushbackBefore(const char *buffer
, wxUint32 size
)
905 if (m_unread
== NULL
)
906 m_unread
= (char *)malloc(size
);
910 tmp
= (char *)malloc(m_unrd_size
+ size
);
911 memcpy(tmp
+size
, m_unread
, m_unrd_size
);
919 memcpy(m_unread
, buffer
, size
);
922 wxUint32
wxSocketBase::GetPushback(char *buffer
, wxUint32 size
, bool peek
)
927 if (size
> (m_unrd_size
-m_unrd_cur
))
928 size
= m_unrd_size
-m_unrd_cur
;
929 memcpy(buffer
, (m_unread
+m_unrd_cur
), size
);
933 if (m_unrd_size
== m_unrd_cur
) {
944 // --------------------------------------------------------------
946 // --------------------------------------------------------------
948 // --------------------------------------------------------------
949 // wxSocketServer ctor and dtor
950 // --------------------------------------------------------------
952 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
954 wxSocketBase(flags
, SOCK_SERVER
)
957 m_socket
= GSocket_new();
962 // Setup the socket as server
963 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
964 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
966 GSocket_destroy(m_socket
);
971 GSocket_SetTimeout(m_socket
, m_timeout
);
972 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
973 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
974 wx_socket_callback
, (char *)this);
978 // --------------------------------------------------------------
979 // wxSocketServer Accept
980 // --------------------------------------------------------------
982 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
984 GSocket
*child_socket
;
989 // GRG: If wait == FALSE, then the call should be nonblocking.
990 // When we are finished, we put the socket to blocking mode
994 GSocket_SetNonBlocking(m_socket
, TRUE
);
996 child_socket
= GSocket_WaitConnection(m_socket
);
999 GSocket_SetNonBlocking(m_socket
, FALSE
);
1001 // GRG: this was not being handled!
1002 if (child_socket
== NULL
)
1005 sock
.m_type
= SOCK_INTERNAL
;
1006 sock
.m_socket
= child_socket
;
1007 sock
.m_connected
= TRUE
;
1009 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
);
1010 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1011 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1012 wx_socket_callback
, (char *)&sock
);
1017 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1019 wxSocketBase
* sock
= new wxSocketBase();
1021 sock
->SetFlags((wxSockFlags
)m_flags
);
1023 if (!AcceptWith(*sock
, wait
))
1029 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1031 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
| GSOCK_LOST_FLAG
);
1034 // --------------------------------------------------------------
1036 // --------------------------------------------------------------
1038 // --------------------------------------------------------------
1039 // wxSocketClient ctor and dtor
1040 // --------------------------------------------------------------
1042 wxSocketClient::wxSocketClient(wxSockFlags _flags
) :
1043 wxSocketBase(_flags
, SOCK_CLIENT
)
1047 wxSocketClient::~wxSocketClient()
1051 // --------------------------------------------------------------
1052 // wxSocketClient Connect functions
1053 // --------------------------------------------------------------
1054 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1061 // This should never happen.
1063 GSocket_destroy(m_socket
);
1065 // Initialize all socket stuff ...
1066 m_socket
= GSocket_new();
1067 m_connected
= FALSE
;
1068 m_establishing
= FALSE
;
1073 GSocket_SetTimeout(m_socket
, m_timeout
);
1075 // GRG: If wait == FALSE, then the call should be nonblocking.
1076 // When we are finished, we put the socket to blocking mode
1080 GSocket_SetNonBlocking(m_socket
, TRUE
);
1082 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1083 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1084 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1085 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1086 wx_socket_callback
, (char *)this);
1089 GSocket_SetNonBlocking(m_socket
, FALSE
);
1091 if (err
!= GSOCK_NOERROR
)
1093 if (err
== GSOCK_WOULDBLOCK
)
1094 m_establishing
= TRUE
;
1103 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1107 if (m_connected
) // Already connected
1110 if (!m_establishing
|| !m_socket
) // No connection in progress
1113 ret
= _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
| GSOCK_LOST_FLAG
);
1115 // GRG: m_connected and m_establishing will be updated in
1116 // OnRequest(), but we do it here anyway because sometimes
1117 // the event might be a bit delayed, and if that happens,
1118 // when WaitOnConnect() returns, m_connected will still be
1119 // FALSE. We have to do it as well in OnRequest because
1120 // maybe WaitOnConnect() is not being used...
1124 m_connected
= GSocket_Select(m_socket
, GSOCK_CONNECTION_FLAG
);
1125 m_establishing
= FALSE
;
1132 // --------------------------------------------------------------
1134 // --------------------------------------------------------------
1136 wxSocketEvent::wxSocketEvent(int id
)
1139 wxEventType type
= (wxEventType
)wxEVT_SOCKET
;
1144 void wxSocketEvent::CopyObject(wxObject
& obj_d
) const
1146 wxSocketEvent
*event
= (wxSocketEvent
*)&obj_d
;
1148 wxEvent::CopyObject(obj_d
);
1150 event
->m_skevt
= m_skevt
;
1151 event
->m_socket
= m_socket
;
1154 // --------------------------------------------------------------------------
1156 // --------------------------------------------------------------------------
1157 class WXDLLEXPORT wxSocketModule
: public wxModule
{
1158 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1161 return GSocket_Init();
1168 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)