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 /////////////////////////////////////////////////////////////////////////////
27 /////////////////////////////////////////////////////////////////////////////
31 #include "wx/object.h"
32 #include "wx/string.h"
35 #include "wx/module.h"
39 /////////////////////////////////////////////////////////////////////////////
41 /////////////////////////////////////////////////////////////////////////////
43 #include "wx/sckaddr.h"
44 #include "wx/socket.h"
47 #define MAX_DISCARD_SIZE (10 * 1024)
49 // what to do within waits
50 #define PROCESS_EVENTS() wxYield()
52 // use wxPostEvent or not
53 #define EXPERIMENTAL_USE_POST 1
55 // --------------------------------------------------------------
57 // --------------------------------------------------------------
59 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
60 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
61 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
62 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
63 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
65 class wxSocketState
: public wxObject
69 GSocketEventFlags m_neededreq
;
71 wxSocketBase::wxSockCbk m_cbk
;
75 wxSocketState() : wxObject() {}
78 // --------------------------------------------------------------
79 // wxSocketBase ctor and dtor
80 // --------------------------------------------------------------
82 wxSocketBase::wxSocketBase(wxSockFlags _flags
, wxSockType _type
) :
84 m_socket(NULL
), m_evt_handler(NULL
), m_id(-1),
85 m_flags(_flags
), m_type(_type
),
86 m_neededreq(0), m_notify_state(FALSE
),
87 m_connected(FALSE
), m_establishing(FALSE
),
88 m_reading(FALSE
), m_writing(FALSE
),
89 m_error(FALSE
), m_lcount(0), m_timeout(600), m_states(),
90 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
91 m_cbk(NULL
), m_cdata(NULL
)
95 wxSocketBase::wxSocketBase() :
97 m_socket(NULL
), m_evt_handler(NULL
), m_id(-1),
98 m_flags(NONE
), m_type(SOCK_UNINIT
),
99 m_neededreq(0), m_notify_state(FALSE
),
100 m_connected(FALSE
), m_establishing(FALSE
),
101 m_reading(FALSE
), m_writing(FALSE
),
102 m_error(FALSE
), m_lcount(0), m_timeout(600), m_states(),
103 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
104 m_cbk(NULL
), m_cdata(NULL
)
108 wxSocketBase::~wxSocketBase()
113 // Shutdown and close the socket
116 // Destroy the GSocket object
118 GSocket_destroy(m_socket
);
121 bool wxSocketBase::Close()
123 // Interrupt pending waits
129 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
130 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
132 // Shutdown the connection
133 GSocket_Shutdown(m_socket
);
135 m_establishing
= FALSE
;
141 // --------------------------------------------------------------
142 // wxSocketBase basic IO operations
143 // --------------------------------------------------------------
145 // All IO operations {Read, Write, ReadMsg, WriteMsg, Peek,
146 // Unread, Discard} update m_error and m_lcount.
148 // TODO: Should Connect, Accept and AcceptWith update m_error?
150 class _wxSocketInternalTimer
: public wxTimer
154 unsigned long m_new_val
;
158 *m_state
= (int)m_new_val
; // Change the value
162 wxSocketBase
& wxSocketBase::Read(char* buffer
, wxUint32 nbytes
)
167 m_lcount
= _Read(buffer
, nbytes
);
169 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
170 if (m_flags
& wxSOCKET_WAITALL
)
171 m_error
= (m_lcount
!= nbytes
);
173 m_error
= (m_lcount
== 0);
175 // Allow read events from now on
181 wxUint32
wxSocketBase::_Read(char* buffer
, wxUint32 nbytes
)
186 // we try this even if the connection has already been closed.
187 total
= GetPushback(buffer
, nbytes
, FALSE
);
191 // If the socket is not connected, or we have got the whole
192 // needed buffer, return immedately
193 if (!m_socket
|| !m_connected
|| !nbytes
)
196 // Possible combinations (they are checked in this order)
198 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
203 if (m_flags
& wxSOCKET_NOWAIT
)
205 GSocket_SetNonBlocking(m_socket
, TRUE
);
206 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
207 GSocket_SetNonBlocking(m_socket
, FALSE
);
212 else if (m_flags
& wxSOCKET_WAITALL
)
214 while (ret
> 0 && nbytes
> 0)
216 if (!(m_flags
& wxSOCKET_BLOCK
) && !WaitForRead())
219 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
231 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForRead())
233 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
243 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, wxUint32 nbytes
)
245 wxUint32 len
, len2
, sig
, total
;
250 unsigned char sig
[4];
251 unsigned char len
[4];
260 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
262 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
265 sig
= (wxUint32
)msg
.sig
[0];
266 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
267 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
268 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
270 if (sig
!= 0xfeeddead)
272 wxLogWarning( _("TCP: invalid signature returned to ReadMsg."));
276 len
= (wxUint32
)msg
.len
[0];
277 len
|= (wxUint32
)(msg
.len
[1] << 8);
278 len
|= (wxUint32
)(msg
.len
[2] << 16);
279 len
|= (wxUint32
)(msg
.len
[3] << 24);
281 //wxLogMessage("Readmsg: %d %d %d %d -> len == %d",
282 // msg.len[0], msg.len[1], msg.len[2], msg.len[3], len);
292 // This check is necessary so that we don't attemp to read if
293 // the msg was zero bytes long.
296 total
= _Read(buffer
, len
);
303 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
306 // NOTE: discarded bytes don't add to m_lcount.
309 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
310 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
311 len2
-= (wxUint32
)discard_len
;
313 while ((discard_len
> 0) && len2
);
315 delete [] discard_buffer
;
320 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
323 sig
= (wxUint32
)msg
.sig
[0];
324 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
325 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
326 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
328 if (sig
!= 0xdeadfeed)
330 //wxLogMessage(wxT("Warning: invalid signature returned to ReadMsg"));
346 wxSocketBase
& wxSocketBase::Peek(char* buffer
, wxUint32 nbytes
)
351 m_lcount
= _Read(buffer
, nbytes
);
352 Pushback(buffer
, m_lcount
);
354 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
355 if (m_flags
& wxSOCKET_WAITALL
)
356 m_error
= (m_lcount
!= nbytes
);
358 m_error
= (m_lcount
== 0);
360 // Allow read events again
366 wxSocketBase
& wxSocketBase::Write(const char *buffer
, wxUint32 nbytes
)
371 m_lcount
= _Write(buffer
, nbytes
);
373 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
374 if (m_flags
& wxSOCKET_WAITALL
)
375 m_error
= (m_lcount
!= nbytes
);
377 m_error
= (m_lcount
== 0);
379 // Allow write events again
385 wxUint32
wxSocketBase::_Write(const char *buffer
, wxUint32 nbytes
)
390 if (!m_connected
|| !m_socket
)
393 // Possible combinations (they are checked in this order)
395 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
400 if (m_flags
& wxSOCKET_NOWAIT
)
402 GSocket_SetNonBlocking(m_socket
, TRUE
);
403 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
404 GSocket_SetNonBlocking(m_socket
, FALSE
);
409 else if (m_flags
& wxSOCKET_WAITALL
)
411 while (ret
> 0 && nbytes
> 0)
413 if (!(m_flags
& wxSOCKET_BLOCK
) && !WaitForWrite())
416 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
428 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForWrite())
430 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
440 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, wxUint32 nbytes
)
446 unsigned char sig
[4];
447 unsigned char len
[4];
456 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
458 // warning about 'cast truncates constant value'
460 # pragma warning(disable: 4310)
461 #endif // __VISUALC__
463 msg
.sig
[0] = (unsigned char) 0xad;
464 msg
.sig
[1] = (unsigned char) 0xde;
465 msg
.sig
[2] = (unsigned char) 0xed;
466 msg
.sig
[3] = (unsigned char) 0xfe;
468 msg
.len
[0] = (unsigned char) nbytes
& 0xff;
469 msg
.len
[1] = (unsigned char) (nbytes
>> 8) & 0xff;
470 msg
.len
[2] = (unsigned char) (nbytes
>> 16) & 0xff;
471 msg
.len
[3] = (unsigned char) (nbytes
>> 24) & 0xff;
473 //wxLogMessage("Writemsg: %d %d %d %d -> %d",
475 // (nbytes >> 8) & 0xff,
476 // (nbytes >> 16) & 0xff,
477 // (nbytes >> 24) & 0xff,
481 if (_Write((char *)&msg
, sizeof(msg
)) < sizeof(msg
))
484 total
= _Write(buffer
, nbytes
);
489 msg
.sig
[0] = (unsigned char) 0xed;
490 msg
.sig
[1] = (unsigned char) 0xfe;
491 msg
.sig
[2] = (unsigned char) 0xad;
492 msg
.sig
[3] = (unsigned char) 0xde;
493 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
495 if ((_Write((char *)&msg
, sizeof(msg
))) < sizeof(msg
))
509 # pragma warning(default: 4310)
510 #endif // __VISUALC__
513 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, wxUint32 nbytes
)
516 Pushback(buffer
, nbytes
);
524 wxSocketBase
& wxSocketBase::Discard()
527 char *my_data
= new char[MAX_DISCARD_SIZE
];
528 wxUint32 recv_size
= MAX_DISCARD_SIZE
;
535 SetFlags(wxSOCKET_NOWAIT
);
537 while (recv_size
== MAX_DISCARD_SIZE
)
539 recv_size
= _Read(my_data
, MAX_DISCARD_SIZE
);
547 // Allow read events again
553 // --------------------------------------------------------------
554 // wxSocketBase get local or peer addresses
555 // --------------------------------------------------------------
557 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
564 peer
= GSocket_GetPeer(m_socket
);
565 addr_man
.SetAddress(peer
);
566 GAddress_destroy(peer
);
571 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
578 local
= GSocket_GetLocal(m_socket
);
579 addr_man
.SetAddress(local
);
580 GAddress_destroy(local
);
585 // --------------------------------------------------------------
586 // wxSocketBase save and restore socket state
587 // --------------------------------------------------------------
589 void wxSocketBase::SaveState()
591 wxSocketState
*state
;
593 state
= new wxSocketState();
595 state
->m_notify_state
= m_notify_state
;
596 state
->m_neededreq
= m_neededreq
;
597 state
->m_flags
= m_flags
;
598 state
->m_cbk
= m_cbk
;
599 state
->m_cdata
= m_cdata
;
601 m_states
.Append(state
);
604 void wxSocketBase::RestoreState()
607 wxSocketState
*state
;
609 node
= m_states
.Last();
613 state
= (wxSocketState
*)node
->Data();
615 SetFlags(state
->m_flags
);
616 m_cbk
= state
->m_cbk
;
617 m_cdata
= state
->m_cdata
;
618 m_neededreq
= state
->m_neededreq
;
619 Notify(state
->m_notify_state
);
626 // --------------------------------------------------------------
627 // wxSocketBase Wait functions
628 // --------------------------------------------------------------
630 // These WaitXXX unctions do not depend on the event system any
631 // longer; instead, they poll the socket, using GSocket_Select()
632 // to check for the specified combination of event flags, until
633 // an event occurs or until the timeout ellapses. The polling
634 // loop calls PROCESS_EVENTS(), so this won't block the GUI.
636 // XXX: Should it honour the wxSOCKET_BLOCK flag ?
638 bool wxSocketBase::_Wait(long seconds
,
640 wxSocketEventFlags flags
)
642 GSocketEventFlags result
;
643 _wxSocketInternalTimer timer
;
647 // Set this to TRUE to interrupt ongoing waits
650 // Check for valid socket
654 // If it is not a server, it must be connected or establishing connection
655 if ((m_type
!= SOCK_SERVER
) && (!m_connected
&& !m_establishing
))
658 // Check for valid timeout value
660 timeout
= seconds
* 1000 + milliseconds
;
662 timeout
= m_timeout
* 1000;
667 timer
.m_state
= &state
;
669 timer
.Start((int)timeout
, TRUE
);
672 // Active polling (without using events)
674 // NOTE: this duplicates some of the code in OnRequest (lost
675 // connection and connection establishment handling) but this
676 // doesn't hurt. It has to be here because the event might
677 // be a bit delayed, and it has to be in OnRequest as well
678 // because maybe the WaitXXX functions are not being used.
680 // Do this at least once (important if timeout == 0, when
681 // we are just polling). Also, if just polling, do not yield.
685 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
687 // The order in which we check events is important; in particular,
688 // GSOCKET_LOST events should be checked last (there might be still
689 // data to read in the incoming queue even after the peer has closed
692 // Incoming connection (server) or connection established (client)
693 if (result
& GSOCK_CONNECTION_FLAG
)
697 m_establishing
= FALSE
;
702 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
709 if (result
& GSOCK_LOST_FLAG
)
717 if ((timeout
== 0) || (m_interrupt
))
727 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
729 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
731 GSOCK_CONNECTION_FLAG
|
735 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
737 // Check pushback buffer
741 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
);
744 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
746 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
749 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
751 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
754 void wxSocketBase::SetTimeout(long seconds
)
759 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
762 // --------------------------------------------------------------
763 // wxSocketBase flags
764 // --------------------------------------------------------------
766 void wxSocketBase::SetFlags(wxSockFlags _flags
)
771 // --------------------------------------------------------------
772 // wxSocketBase callback management
773 // --------------------------------------------------------------
775 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
777 wxSockCbk old_cbk
= cbk_
;
783 char *wxSocketBase::CallbackData(char *data
)
785 char *old_data
= m_cdata
;
791 // --------------------------------------------------------------
792 // wxSocketBase automatic notifier
793 // --------------------------------------------------------------
795 // All events (INPUT, OUTPUT, CONNECTION, LOST) are now always
796 // internally watched; but users will only be notified of those
797 // events they are interested in.
799 static void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
800 GSocketEvent event
, char *cdata
)
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 // dbg("Entering OnRequest (evt %d)\n", req_evt);
838 // This duplicates some code in _Wait(), but this doesn't hurt.
839 // It has to be here because we don't know whether the Wait()
840 // functions will be used, and it has to be in _Wait as well
841 // because the event might be a bit delayed.
843 // The order in which we check events is important; in particular,
844 // GSOCKET_LOST events should be checked last (there might be still
845 // data to read in the incoming queue even after the peer has
846 // closed the connection).
848 case wxSOCKET_CONNECTION
:
849 m_establishing
= FALSE
;
853 // If we are in the middle of a R/W operation, do not
854 // propagate events to users. Also, filter 'late' events
855 // which are no longer valid.
858 if (m_reading
|| !GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
863 case wxSOCKET_OUTPUT
:
864 if (m_writing
|| !GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
))
874 if (((m_neededreq
& flag
) == flag
) && m_notify_state
)
876 // dbg("Evt %d delivered\n", req_evt);
877 event
.m_socket
= this;
878 event
.m_skevt
= req_evt
;
881 #if EXPERIMENTAL_USE_POST
882 wxPostEvent(m_evt_handler
, event
);
887 OldOnNotify(req_evt
);
889 m_cbk(*this, req_evt
, m_cdata
);
893 // dbg("Exiting OnRequest (evt %d)\n", req_evt);
896 void wxSocketBase::OldOnNotify(wxSocketNotify
WXUNUSED(evt
))
900 // --------------------------------------------------------------
901 // wxSocketBase set event handler
902 // --------------------------------------------------------------
904 void wxSocketBase::SetEventHandler(wxEvtHandler
& h_evt
, int id
)
906 m_evt_handler
= &h_evt
;
909 SetNextHandler(&h_evt
);
912 // --------------------------------------------------------------
913 // wxSocketBase pushback
914 // --------------------------------------------------------------
916 void wxSocketBase::Pushback(const char *buffer
, wxUint32 size
)
920 if (m_unread
== NULL
)
921 m_unread
= (char *)malloc(size
);
926 tmp
= (char *)malloc(m_unrd_size
+ size
);
927 memcpy(tmp
+size
, m_unread
, m_unrd_size
);
935 memcpy(m_unread
, buffer
, size
);
938 wxUint32
wxSocketBase::GetPushback(char *buffer
, wxUint32 size
, bool peek
)
943 if (size
> (m_unrd_size
-m_unrd_cur
))
944 size
= m_unrd_size
-m_unrd_cur
;
946 memcpy(buffer
, (m_unread
+m_unrd_cur
), size
);
951 if (m_unrd_size
== m_unrd_cur
)
963 // --------------------------------------------------------------
965 // --------------------------------------------------------------
967 // --------------------------------------------------------------
968 // wxSocketServer ctor and dtor
969 // --------------------------------------------------------------
971 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
973 wxSocketBase(flags
, SOCK_SERVER
)
976 m_socket
= GSocket_new();
981 // Setup the socket as server
982 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
983 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
985 GSocket_destroy(m_socket
);
990 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
991 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
992 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
993 wx_socket_callback
, (char *)this);
997 // --------------------------------------------------------------
998 // wxSocketServer Accept
999 // --------------------------------------------------------------
1001 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1003 GSocket
*child_socket
;
1008 // GRG: If wait == FALSE, then the call should be nonblocking.
1009 // When we are finished, we put the socket to blocking mode
1013 GSocket_SetNonBlocking(m_socket
, TRUE
);
1015 child_socket
= GSocket_WaitConnection(m_socket
);
1018 GSocket_SetNonBlocking(m_socket
, FALSE
);
1020 // GRG: this was not being handled!
1021 if (child_socket
== NULL
)
1024 sock
.m_type
= SOCK_INTERNAL
;
1025 sock
.m_socket
= child_socket
;
1026 sock
.m_connected
= TRUE
;
1028 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
* 1000);
1029 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1030 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1031 wx_socket_callback
, (char *)&sock
);
1036 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1038 wxSocketBase
* sock
= new wxSocketBase();
1040 sock
->SetFlags((wxSockFlags
)m_flags
);
1042 if (!AcceptWith(*sock
, wait
))
1048 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1050 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1053 // --------------------------------------------------------------
1055 // --------------------------------------------------------------
1057 // --------------------------------------------------------------
1058 // wxSocketClient ctor and dtor
1059 // --------------------------------------------------------------
1061 wxSocketClient::wxSocketClient(wxSockFlags _flags
) :
1062 wxSocketBase(_flags
, SOCK_CLIENT
)
1066 wxSocketClient::~wxSocketClient()
1070 // --------------------------------------------------------------
1071 // wxSocketClient Connect functions
1072 // --------------------------------------------------------------
1074 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1081 // This should never happen.
1083 GSocket_destroy(m_socket
);
1085 // Initialize all socket stuff ...
1086 m_socket
= GSocket_new();
1087 m_connected
= FALSE
;
1088 m_establishing
= FALSE
;
1093 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1094 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1095 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1096 wx_socket_callback
, (char *)this);
1098 // GRG: If wait == FALSE, then the call should be nonblocking.
1099 // When we are finished, we put the socket to blocking mode
1103 GSocket_SetNonBlocking(m_socket
, TRUE
);
1105 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1106 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1109 GSocket_SetNonBlocking(m_socket
, FALSE
);
1111 if (err
!= GSOCK_NOERROR
)
1113 if (err
== GSOCK_WOULDBLOCK
)
1114 m_establishing
= TRUE
;
1123 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1125 if (m_connected
) // Already connected
1128 if (!m_establishing
|| !m_socket
) // No connection in progress
1131 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1134 // --------------------------------------------------------------
1136 // --------------------------------------------------------------
1138 /* NOTE: experimental stuff - might change */
1140 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
, wxSockFlags flags
)
1141 : wxSocketBase( flags
, SOCK_DATAGRAM
)
1143 // Create the socket
1144 m_socket
= GSocket_new();
1149 // Setup the socket as non connection oriented
1150 GSocket_SetLocal(m_socket
, addr
.GetAddress());
1151 if( GSocket_SetNonOriented(m_socket
) != GSOCK_NOERROR
)
1153 GSocket_destroy(m_socket
);
1158 // Initialize all stuff
1159 m_connected
= FALSE
;
1160 m_establishing
= FALSE
;
1161 GSocket_SetTimeout( m_socket
, m_timeout
);
1162 GSocket_SetCallback( m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1163 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1164 wx_socket_callback
, (char*)this );
1168 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1177 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1181 GSocket_SetPeer(m_socket
, addr
.GetAddress());
1186 // --------------------------------------------------------------
1188 // --------------------------------------------------------------
1190 wxSocketEvent::wxSocketEvent(int id
)
1193 wxEventType type
= (wxEventType
)wxEVT_SOCKET
;
1198 void wxSocketEvent::CopyObject(wxObject
& obj_d
) const
1200 wxSocketEvent
*event
= (wxSocketEvent
*)&obj_d
;
1202 wxEvent::CopyObject(obj_d
);
1204 event
->m_skevt
= m_skevt
;
1205 event
->m_socket
= m_socket
;
1208 // --------------------------------------------------------------------------
1210 // --------------------------------------------------------------------------
1212 class WXDLLEXPORT wxSocketModule
: public wxModule
1214 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1218 return GSocket_Init();
1226 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)