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 /////////////////////////////////////////////////////////////////////////////
31 #include "wx/object.h"
32 #include "wx/string.h"
35 #include "wx/module.h"
43 /////////////////////////////////////////////////////////////////////////////
45 /////////////////////////////////////////////////////////////////////////////
47 #include "wx/sckaddr.h"
48 #include "wx/socket.h"
51 #define PROCESS_EVENTS() wxYield()
54 // --------------------------------------------------------------
56 // --------------------------------------------------------------
58 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
59 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
60 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
61 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
63 class wxSocketState
: public wxObject
67 GSocketEventFlags m_neededreq
;
69 wxSocketBase::wxSockCbk m_cbk
;
73 wxSocketState() : wxObject() {}
76 // --------------------------------------------------------------
77 // wxSocketBase ctor and dtor
78 // --------------------------------------------------------------
80 wxSocketBase::wxSocketBase(wxSockFlags _flags
, wxSockType _type
) :
82 m_socket(NULL
), m_id(-1),
83 m_flags(_flags
), m_type(_type
),
84 m_neededreq(0), m_notify_state(FALSE
),
85 m_connected(FALSE
), m_establishing(FALSE
),
86 m_reading(FALSE
), m_writing(FALSE
),
87 m_error(FALSE
), m_lcount(0), m_timeout(600), m_states(),
88 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
89 m_cbk(NULL
), m_cdata(NULL
)
93 wxSocketBase::wxSocketBase() :
95 m_socket(NULL
), m_id(-1),
96 m_flags(NONE
), m_type(SOCK_UNINIT
),
97 m_neededreq(0), m_notify_state(FALSE
),
98 m_connected(FALSE
), m_establishing(FALSE
),
99 m_reading(FALSE
), m_writing(FALSE
),
100 m_error(FALSE
), m_lcount(0), m_timeout(600), m_states(),
101 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
102 m_cbk(NULL
), m_cdata(NULL
)
106 wxSocketBase::~wxSocketBase()
111 // Shutdown and close the socket
114 // Destroy the GSocket object
116 GSocket_destroy(m_socket
);
119 bool wxSocketBase::Close()
121 // Interrupt pending waits
127 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
128 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
130 // Shutdown the connection
131 GSocket_Shutdown(m_socket
);
133 m_establishing
= FALSE
;
139 // --------------------------------------------------------------
140 // wxSocketBase basic IO operations
141 // --------------------------------------------------------------
143 // All IO operations {Read, Write, ReadMsg, WriteMsg, Peek,
144 // Unread, Discard} update m_error and m_lcount.
146 // TODO: Should Connect, Accept and AcceptWith update m_error?
148 class _wxSocketInternalTimer
: public wxTimer
152 unsigned long m_new_val
;
156 *m_state
= (int)m_new_val
; // Change the value
160 wxSocketBase
& wxSocketBase::Read(char* buffer
, wxUint32 nbytes
)
165 m_lcount
= _Read(buffer
, nbytes
);
167 // If in WAITALL mode, all bytes should have been read.
168 if (m_flags
& WAITALL
)
169 m_error
= (m_lcount
!= nbytes
);
171 m_error
= (m_lcount
== 0);
173 // Trigger another read event if there is still data available.
180 wxUint32
wxSocketBase::_Read(char* buffer
, wxUint32 nbytes
)
185 // we try this even if the connection has already been closed.
186 total
= GetPushback(buffer
, nbytes
, FALSE
);
190 // If the socket is not connected, or we have got the whole
191 // needed buffer, return immedately
192 if (!m_connected
|| !m_socket
|| !nbytes
)
195 // Possible combinations (they are checked in this order)
197 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
202 if (m_flags
& wxSOCKET_NOWAIT
)
204 GSocket_SetNonBlocking(m_socket
, TRUE
);
205 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
206 GSocket_SetNonBlocking(m_socket
, FALSE
);
211 else if (m_flags
& wxSOCKET_WAITALL
) // wxSOCKET_WAITALL
213 while (ret
> 0 && nbytes
> 0)
215 if (!(m_flags
& wxSOCKET_BLOCK
) && !(WaitForRead()))
218 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
230 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForRead())
232 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
242 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, wxUint32 nbytes
)
244 #define MAX_DISCARD_SIZE (10 * 1024)
246 wxUint32 len
, len2
, sig
, total
;
251 unsigned char sig
[4];
252 unsigned char len
[4];
261 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
263 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
266 sig
= (wxUint32
)msg
.sig
[0];
267 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
268 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
269 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
271 if (sig
!= 0xfeeddead)
273 wxLogWarning( _("TCP: invalid signature returned to ReadMsg."));
277 len
= (wxUint32
)msg
.len
[0];
278 len
|= (wxUint32
)(msg
.len
[1] << 8);
279 len
|= (wxUint32
)(msg
.len
[2] << 16);
280 len
|= (wxUint32
)(msg
.len
[3] << 24);
282 //wxLogMessage("Readmsg: %d %d %d %d -> len == %d",
283 // msg.len[0], msg.len[1], msg.len[2], msg.len[3], len);
293 // This check is necessary so that we don't attemp to read if
294 // the msg was zero bytes long.
297 total
= _Read(buffer
, len
);
304 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
307 // NOTE: discarded bytes don't add to m_lcount.
310 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
311 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
312 len2
-= (wxUint32
)discard_len
;
314 while ((discard_len
> 0) && len2
);
316 delete [] discard_buffer
;
321 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
324 sig
= (wxUint32
)msg
.sig
[0];
325 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
326 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
327 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
329 if (sig
!= 0xdeadfeed)
331 //wxLogMessage(wxT("Warning: invalid signature returned to ReadMsg"));
347 #undef MAX_DISCARD_SIZE
350 wxSocketBase
& wxSocketBase::Peek(char* buffer
, wxUint32 nbytes
)
355 m_lcount
= _Read(buffer
, nbytes
);
356 Pushback(buffer
, nbytes
);
358 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
359 if (m_flags
& wxSOCKET_WAITALL
)
360 m_error
= (m_lcount
!= nbytes
);
362 m_error
= (m_lcount
== 0);
364 // Trigger another read event if there is still data available.
371 wxSocketBase
& wxSocketBase::Write(const char *buffer
, wxUint32 nbytes
)
376 m_lcount
= _Write(buffer
, nbytes
);
378 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
379 if (m_flags
& wxSOCKET_WAITALL
)
380 m_error
= (m_lcount
!= nbytes
);
382 m_error
= (m_lcount
== 0);
384 // Trigger another write event if the socket is still writable
387 // TODO: TriggerWrite
391 wxUint32
wxSocketBase::_Write(const char *buffer
, wxUint32 nbytes
)
396 if (!m_connected
|| !m_socket
)
399 // Possible combinations (they are checked in this order)
401 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
406 if (m_flags
& wxSOCKET_NOWAIT
)
408 GSocket_SetNonBlocking(m_socket
, TRUE
);
409 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
410 GSocket_SetNonBlocking(m_socket
, FALSE
);
415 else if (m_flags
& wxSOCKET_WAITALL
)
417 while (ret
> 0 && nbytes
> 0)
419 if (!(m_flags
& wxSOCKET_BLOCK
) && !(WaitForWrite()))
422 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
434 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForWrite())
436 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
446 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, wxUint32 nbytes
)
452 unsigned char sig
[4];
453 unsigned char len
[4];
462 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
464 // warning about 'cast truncates constant value'
466 # pragma warning(disable: 4310)
467 #endif // __VISUALC__
469 msg
.sig
[0] = (unsigned char) 0xad;
470 msg
.sig
[1] = (unsigned char) 0xde;
471 msg
.sig
[2] = (unsigned char) 0xed;
472 msg
.sig
[3] = (unsigned char) 0xfe;
474 msg
.len
[0] = (unsigned char) nbytes
& 0xff;
475 msg
.len
[1] = (unsigned char) (nbytes
>> 8) & 0xff;
476 msg
.len
[2] = (unsigned char) (nbytes
>> 16) & 0xff;
477 msg
.len
[3] = (unsigned char) (nbytes
>> 24) & 0xff;
479 //wxLogMessage("Writemsg: %d %d %d %d -> %d",
481 // (nbytes >> 8) & 0xff,
482 // (nbytes >> 16) & 0xff,
483 // (nbytes >> 24) & 0xff,
487 if (_Write((char *)&msg
, sizeof(msg
)) < sizeof(msg
))
490 total
= _Write(buffer
, nbytes
);
495 msg
.sig
[0] = (unsigned char) 0xed;
496 msg
.sig
[1] = (unsigned char) 0xfe;
497 msg
.sig
[2] = (unsigned char) 0xad;
498 msg
.sig
[3] = (unsigned char) 0xde;
499 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
501 if ((_Write((char *)&msg
, sizeof(msg
))) < sizeof(msg
))
512 // TODO: TriggerWrite
516 # pragma warning(default: 4310)
517 #endif // __VISUALC__
520 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, wxUint32 nbytes
)
523 Pushback(buffer
, nbytes
);
531 wxSocketBase
& wxSocketBase::Discard()
533 #define MAX_BUFSIZE (10*1024)
536 char *my_data
= new char[MAX_BUFSIZE
];
537 wxUint32 recv_size
= MAX_BUFSIZE
;
544 SetFlags(wxSOCKET_NOWAIT
);
546 while (recv_size
== MAX_BUFSIZE
)
548 recv_size
= _Read(my_data
, MAX_BUFSIZE
);
556 // Trigger another read event if there is still data available.
565 // --------------------------------------------------------------
566 // wxSocketBase get local or peer addresses
567 // --------------------------------------------------------------
569 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
576 peer
= GSocket_GetPeer(m_socket
);
577 addr_man
.SetAddress(peer
);
578 GAddress_destroy(peer
);
583 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
590 local
= GSocket_GetLocal(m_socket
);
591 addr_man
.SetAddress(local
);
592 GAddress_destroy(local
);
597 // --------------------------------------------------------------
598 // wxSocketBase save and restore socket state
599 // --------------------------------------------------------------
601 void wxSocketBase::SaveState()
603 wxSocketState
*state
;
605 state
= new wxSocketState();
607 state
->m_notify_state
= m_notify_state
;
608 state
->m_neededreq
= m_neededreq
;
609 state
->m_flags
= m_flags
;
610 state
->m_cbk
= m_cbk
;
611 state
->m_cdata
= m_cdata
;
613 m_states
.Append(state
);
616 void wxSocketBase::RestoreState()
619 wxSocketState
*state
;
621 node
= m_states
.Last();
625 state
= (wxSocketState
*)node
->Data();
627 SetFlags(state
->m_flags
);
628 m_cbk
= state
->m_cbk
;
629 m_cdata
= state
->m_cdata
;
630 m_neededreq
= state
->m_neededreq
;
631 Notify(state
->m_notify_state
);
638 // --------------------------------------------------------------
639 // wxSocketBase Wait functions
640 // --------------------------------------------------------------
642 // GRG: I have completely rewritten this family of functions
643 // so that they don't depend on event notifications; instead,
644 // they poll the socket, using GSocket_Select(), to check for
645 // the specified combination of event flags, until an event
646 // occurs or until the timeout ellapses. The polling loop
647 // calls PROCESS_EVENTS(), so this won't block the GUI.
649 bool wxSocketBase::_Wait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
651 GSocketEventFlags result
;
652 _wxSocketInternalTimer timer
;
656 // Set this to TRUE to interrupt ongoing waits
659 // Check for valid socket
663 // If it is not a server, it must be connected or establishing connection
664 if ((m_type
!= SOCK_SERVER
) && (!m_connected
&& !m_establishing
))
667 // Check for valid timeout value
669 timeout
= seconds
* 1000 + milliseconds
;
671 timeout
= m_timeout
* 1000;
676 timer
.m_state
= &state
;
678 timer
.Start((int)timeout
, TRUE
);
681 // Active polling (without using events)
683 // NOTE: this duplicates some of the code in OnRequest (lost
684 // connection and connection establishment handling) but this
685 // doesn't hurt. It has to be here because the event might
686 // be a bit delayed, and it has to be in OnRequest as well
687 // because maybe the WaitXXX functions are not being used.
689 // Do this at least once (important if timeout == 0, when
690 // we are just polling)
694 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
697 if (result
& GSOCK_LOST_FLAG
)
704 // Incoming connection (server) or connection established (client)
705 if (result
& GSOCK_CONNECTION_FLAG
)
709 m_establishing
= FALSE
;
713 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
720 if ((timeout
== 0) || (m_interrupt
))
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 // Check pushback buffer
744 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
);
747 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
749 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
752 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
754 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
757 void wxSocketBase::SetTimeout(long seconds
)
762 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
765 // --------------------------------------------------------------
766 // wxSocketBase flags
767 // --------------------------------------------------------------
769 void wxSocketBase::SetFlags(wxSockFlags _flags
)
774 // --------------------------------------------------------------
775 // wxSocketBase callback management
776 // --------------------------------------------------------------
778 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
780 wxSockCbk old_cbk
= cbk_
;
786 char *wxSocketBase::CallbackData(char *data
)
788 char *old_data
= m_cdata
;
794 // --------------------------------------------------------------
795 // wxSocketBase automatic notifier
796 // --------------------------------------------------------------
798 // All events (INPUT, OUTPUT, CONNECTION, LOST) are now always
799 // internally watched; but users will only be notified of those
800 // events they are interested in.
802 static void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
803 GSocketEvent event
, char *cdata
)
805 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
807 sckobj
->OnRequest((wxSocketNotify
)event
);
810 wxSocketEventFlags
wxSocketBase::EventToNotify(wxSocketNotify evt
)
814 case GSOCK_INPUT
: return GSOCK_INPUT_FLAG
;
815 case GSOCK_OUTPUT
: return GSOCK_OUTPUT_FLAG
;
816 case GSOCK_CONNECTION
: return GSOCK_CONNECTION_FLAG
;
817 case GSOCK_LOST
: return GSOCK_LOST_FLAG
;
822 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
827 void wxSocketBase::Notify(bool notify
)
829 m_notify_state
= notify
;
832 void wxSocketBase::OnRequest(wxSocketNotify req_evt
)
834 wxSocketEvent
event(m_id
);
835 wxSocketEventFlags flag
= EventToNotify(req_evt
);
837 // fprintf(stderr, "%s: Entering OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
839 // NOTE: this duplicates some of the code in _Wait, (lost
840 // connections and delayed connection establishment) but
841 // this doesn't hurt. It has to be here because maybe the
842 // WaitXXX are not being used, and it has to be in _Wait
843 // as well because the event might be a bit delayed.
847 case wxSOCKET_CONNECTION
:
848 m_establishing
= FALSE
;
855 // If we are in the middle of a R/W operation, do not
856 // propagate events to users.
859 if (m_reading
) return;
861 case wxSOCKET_OUTPUT
:
862 if (m_writing
) return;
865 if (((m_neededreq
& flag
) == flag
) && m_notify_state
)
867 // fprintf(stderr, "%s: Evt %d delivered\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
868 event
.m_socket
= this;
869 event
.m_skevt
= req_evt
;
870 ProcessEvent(event
); // XXX - should be PostEvent
872 OldOnNotify(req_evt
);
874 m_cbk(*this, req_evt
, m_cdata
);
878 // fprintf(stderr, "%s: Exiting OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
881 void wxSocketBase::OldOnNotify(wxSocketNotify
WXUNUSED(evt
))
885 // --------------------------------------------------------------
886 // wxSocketBase set event handler
887 // --------------------------------------------------------------
889 void wxSocketBase::SetEventHandler(wxEvtHandler
& h_evt
, int id
)
891 SetNextHandler(&h_evt
);
895 // --------------------------------------------------------------
896 // wxSocketBase pushback
897 // --------------------------------------------------------------
899 void wxSocketBase::Pushback(const char *buffer
, wxUint32 size
)
901 if (m_unread
== NULL
)
902 m_unread
= (char *)malloc(size
);
906 tmp
= (char *)malloc(m_unrd_size
+ size
);
907 memcpy(tmp
+size
, m_unread
, m_unrd_size
);
915 memcpy(m_unread
, buffer
, size
);
918 wxUint32
wxSocketBase::GetPushback(char *buffer
, wxUint32 size
, bool peek
)
923 if (size
> (m_unrd_size
-m_unrd_cur
))
924 size
= m_unrd_size
-m_unrd_cur
;
926 memcpy(buffer
, (m_unread
+m_unrd_cur
), size
);
930 if (m_unrd_size
== m_unrd_cur
) {
941 // --------------------------------------------------------------
943 // --------------------------------------------------------------
945 // --------------------------------------------------------------
946 // wxSocketServer ctor and dtor
947 // --------------------------------------------------------------
949 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
951 wxSocketBase(flags
, SOCK_SERVER
)
954 m_socket
= GSocket_new();
959 // Setup the socket as server
960 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
961 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
963 GSocket_destroy(m_socket
);
968 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
969 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
970 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
971 wx_socket_callback
, (char *)this);
975 // --------------------------------------------------------------
976 // wxSocketServer Accept
977 // --------------------------------------------------------------
979 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
981 GSocket
*child_socket
;
986 // GRG: If wait == FALSE, then the call should be nonblocking.
987 // When we are finished, we put the socket to blocking mode
991 GSocket_SetNonBlocking(m_socket
, TRUE
);
993 child_socket
= GSocket_WaitConnection(m_socket
);
996 GSocket_SetNonBlocking(m_socket
, FALSE
);
998 // GRG: this was not being handled!
999 if (child_socket
== NULL
)
1002 sock
.m_type
= SOCK_INTERNAL
;
1003 sock
.m_socket
= child_socket
;
1004 sock
.m_connected
= TRUE
;
1006 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
* 1000);
1007 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1008 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1009 wx_socket_callback
, (char *)&sock
);
1014 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1016 wxSocketBase
* sock
= new wxSocketBase();
1018 sock
->SetFlags((wxSockFlags
)m_flags
);
1020 if (!AcceptWith(*sock
, wait
))
1026 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1028 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1031 // --------------------------------------------------------------
1033 // --------------------------------------------------------------
1035 // --------------------------------------------------------------
1036 // wxSocketClient ctor and dtor
1037 // --------------------------------------------------------------
1039 wxSocketClient::wxSocketClient(wxSockFlags _flags
) :
1040 wxSocketBase(_flags
, SOCK_CLIENT
)
1044 wxSocketClient::~wxSocketClient()
1048 // --------------------------------------------------------------
1049 // wxSocketClient Connect functions
1050 // --------------------------------------------------------------
1051 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1058 // This should never happen.
1060 GSocket_destroy(m_socket
);
1062 // Initialize all socket stuff ...
1063 m_socket
= GSocket_new();
1064 m_connected
= FALSE
;
1065 m_establishing
= FALSE
;
1070 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1071 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1072 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1073 wx_socket_callback
, (char *)this);
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
);
1086 GSocket_SetNonBlocking(m_socket
, FALSE
);
1088 if (err
!= GSOCK_NOERROR
)
1090 if (err
== GSOCK_WOULDBLOCK
)
1091 m_establishing
= TRUE
;
1100 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1102 if (m_connected
) // Already connected
1105 if (!m_establishing
|| !m_socket
) // No connection in progress
1108 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1111 // --------------------------------------------------------------
1113 // --------------------------------------------------------------
1115 wxSocketEvent::wxSocketEvent(int id
)
1118 wxEventType type
= (wxEventType
)wxEVT_SOCKET
;
1123 void wxSocketEvent::CopyObject(wxObject
& obj_d
) const
1125 wxSocketEvent
*event
= (wxSocketEvent
*)&obj_d
;
1127 wxEvent::CopyObject(obj_d
);
1129 event
->m_skevt
= m_skevt
;
1130 event
->m_socket
= m_socket
;
1133 // --------------------------------------------------------------------------
1135 // --------------------------------------------------------------------------
1136 class WXDLLEXPORT wxSocketModule
: public wxModule
{
1137 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1140 return GSocket_Init();
1147 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)