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 /////////////////////////////////////////////////////////////////////////////
32 #include "wx/object.h"
33 #include "wx/string.h"
36 #include "wx/module.h"
40 /////////////////////////////////////////////////////////////////////////////
42 /////////////////////////////////////////////////////////////////////////////
44 #include "wx/sckaddr.h"
45 #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 EXPERIMENTAL_USE_POST 1
57 // --------------------------------------------------------------
59 // --------------------------------------------------------------
61 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
62 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
63 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
64 IMPLEMENT_CLASS(wxDatagramSocket
, wxSocketBase
)
65 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
67 class wxSocketState
: public wxObject
71 GSocketEventFlags m_neededreq
;
73 wxSocketBase::wxSockCbk m_cbk
;
77 wxSocketState() : wxObject() {}
80 // --------------------------------------------------------------
81 // wxSocketBase ctor and dtor
82 // --------------------------------------------------------------
84 wxSocketBase::wxSocketBase(wxSockFlags _flags
, wxSockType _type
) :
86 m_socket(NULL
), m_evt_handler(NULL
), m_id(-1),
87 m_flags(_flags
), m_type(_type
),
88 m_neededreq(0), m_notify_state(FALSE
),
89 m_connected(FALSE
), m_establishing(FALSE
),
90 m_reading(FALSE
), m_writing(FALSE
),
91 m_error(FALSE
), m_lcount(0), m_timeout(600), m_states(),
92 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
93 m_cbk(NULL
), m_cdata(NULL
)
97 wxSocketBase::wxSocketBase() :
99 m_socket(NULL
), m_evt_handler(NULL
), m_id(-1),
100 m_flags(NONE
), m_type(SOCK_UNINIT
),
101 m_neededreq(0), m_notify_state(FALSE
),
102 m_connected(FALSE
), m_establishing(FALSE
),
103 m_reading(FALSE
), m_writing(FALSE
),
104 m_error(FALSE
), m_lcount(0), m_timeout(600), m_states(),
105 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
106 m_cbk(NULL
), m_cdata(NULL
)
110 wxSocketBase::~wxSocketBase()
115 // Shutdown and close the socket
118 // Destroy the GSocket object
120 GSocket_destroy(m_socket
);
123 bool wxSocketBase::Close()
125 // Interrupt pending waits
131 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
132 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
134 // Shutdown the connection
135 GSocket_Shutdown(m_socket
);
137 m_establishing
= FALSE
;
143 // --------------------------------------------------------------
144 // wxSocketBase basic IO operations
145 // --------------------------------------------------------------
147 // All IO operations {Read, Write, ReadMsg, WriteMsg, Peek,
148 // Unread, Discard} update m_error and m_lcount.
150 // TODO: Should Connect, Accept and AcceptWith update m_error?
152 class _wxSocketInternalTimer
: public wxTimer
156 unsigned long m_new_val
;
160 *m_state
= (int)m_new_val
; // Change the value
164 wxSocketBase
& wxSocketBase::Read(char* buffer
, wxUint32 nbytes
)
169 m_lcount
= _Read(buffer
, nbytes
);
171 // If in WAITALL mode, all bytes should have been read.
172 if (m_flags
& WAITALL
)
173 m_error
= (m_lcount
!= nbytes
);
175 m_error
= (m_lcount
== 0);
177 // Allow read events from now on
183 wxUint32
wxSocketBase::_Read(char* buffer
, wxUint32 nbytes
)
188 // we try this even if the connection has already been closed.
189 total
= GetPushback(buffer
, nbytes
, FALSE
);
193 // If the socket is not connected, or we have got the whole
194 // needed buffer, return immedately
195 if (!m_socket
|| !m_connected
|| !nbytes
)
198 // Possible combinations (they are checked in this order)
200 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
205 if (m_flags
& wxSOCKET_NOWAIT
)
207 GSocket_SetNonBlocking(m_socket
, TRUE
);
208 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
209 GSocket_SetNonBlocking(m_socket
, FALSE
);
214 else if (m_flags
& wxSOCKET_WAITALL
)
216 while (ret
> 0 && nbytes
> 0)
218 if (!(m_flags
& wxSOCKET_BLOCK
) && !(WaitForRead()))
221 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
233 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForRead())
235 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
245 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, wxUint32 nbytes
)
247 wxUint32 len
, len2
, sig
, total
;
252 unsigned char sig
[4];
253 unsigned char len
[4];
262 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
264 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
267 sig
= (wxUint32
)msg
.sig
[0];
268 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
269 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
270 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
272 if (sig
!= 0xfeeddead)
274 wxLogWarning( _("TCP: invalid signature returned to ReadMsg."));
278 len
= (wxUint32
)msg
.len
[0];
279 len
|= (wxUint32
)(msg
.len
[1] << 8);
280 len
|= (wxUint32
)(msg
.len
[2] << 16);
281 len
|= (wxUint32
)(msg
.len
[3] << 24);
283 //wxLogMessage("Readmsg: %d %d %d %d -> len == %d",
284 // msg.len[0], msg.len[1], msg.len[2], msg.len[3], len);
294 // This check is necessary so that we don't attemp to read if
295 // the msg was zero bytes long.
298 total
= _Read(buffer
, len
);
305 char *discard_buffer
= new char[MAX_DISCARD_SIZE
];
308 // NOTE: discarded bytes don't add to m_lcount.
311 discard_len
= ((len2
> MAX_DISCARD_SIZE
)? MAX_DISCARD_SIZE
: len2
);
312 discard_len
= _Read(discard_buffer
, (wxUint32
)discard_len
);
313 len2
-= (wxUint32
)discard_len
;
315 while ((discard_len
> 0) && len2
);
317 delete [] discard_buffer
;
322 if (_Read((char *)&msg
, sizeof(msg
)) != sizeof(msg
))
325 sig
= (wxUint32
)msg
.sig
[0];
326 sig
|= (wxUint32
)(msg
.sig
[1] << 8);
327 sig
|= (wxUint32
)(msg
.sig
[2] << 16);
328 sig
|= (wxUint32
)(msg
.sig
[3] << 24);
330 if (sig
!= 0xdeadfeed)
332 //wxLogMessage(wxT("Warning: invalid signature returned to ReadMsg"));
348 wxSocketBase
& wxSocketBase::Peek(char* buffer
, wxUint32 nbytes
)
353 m_lcount
= _Read(buffer
, nbytes
);
354 Pushback(buffer
, m_lcount
);
356 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
357 if (m_flags
& wxSOCKET_WAITALL
)
358 m_error
= (m_lcount
!= nbytes
);
360 m_error
= (m_lcount
== 0);
362 // Allow read events again
368 wxSocketBase
& wxSocketBase::Write(const char *buffer
, wxUint32 nbytes
)
373 m_lcount
= _Write(buffer
, nbytes
);
375 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
376 if (m_flags
& wxSOCKET_WAITALL
)
377 m_error
= (m_lcount
!= nbytes
);
379 m_error
= (m_lcount
== 0);
381 // Allow write events again
387 wxUint32
wxSocketBase::_Write(const char *buffer
, wxUint32 nbytes
)
392 if (!m_connected
|| !m_socket
)
395 // Possible combinations (they are checked in this order)
397 // wxSOCKET_WAITALL | wxSOCKET_BLOCK
402 if (m_flags
& wxSOCKET_NOWAIT
)
404 GSocket_SetNonBlocking(m_socket
, TRUE
);
405 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
406 GSocket_SetNonBlocking(m_socket
, FALSE
);
411 else if (m_flags
& wxSOCKET_WAITALL
)
413 while (ret
> 0 && nbytes
> 0)
415 if (!(m_flags
& wxSOCKET_BLOCK
) && !(WaitForWrite()))
418 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
430 if ((m_flags
& wxSOCKET_BLOCK
) || WaitForWrite())
432 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
442 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, wxUint32 nbytes
)
448 unsigned char sig
[4];
449 unsigned char len
[4];
458 SetFlags((m_flags
& wxSOCKET_BLOCK
) | wxSOCKET_WAITALL
);
460 // warning about 'cast truncates constant value'
462 # pragma warning(disable: 4310)
463 #endif // __VISUALC__
465 msg
.sig
[0] = (unsigned char) 0xad;
466 msg
.sig
[1] = (unsigned char) 0xde;
467 msg
.sig
[2] = (unsigned char) 0xed;
468 msg
.sig
[3] = (unsigned char) 0xfe;
470 msg
.len
[0] = (unsigned char) nbytes
& 0xff;
471 msg
.len
[1] = (unsigned char) (nbytes
>> 8) & 0xff;
472 msg
.len
[2] = (unsigned char) (nbytes
>> 16) & 0xff;
473 msg
.len
[3] = (unsigned char) (nbytes
>> 24) & 0xff;
475 //wxLogMessage("Writemsg: %d %d %d %d -> %d",
477 // (nbytes >> 8) & 0xff,
478 // (nbytes >> 16) & 0xff,
479 // (nbytes >> 24) & 0xff,
483 if (_Write((char *)&msg
, sizeof(msg
)) < sizeof(msg
))
486 total
= _Write(buffer
, nbytes
);
491 msg
.sig
[0] = (unsigned char) 0xed;
492 msg
.sig
[1] = (unsigned char) 0xfe;
493 msg
.sig
[2] = (unsigned char) 0xad;
494 msg
.sig
[3] = (unsigned char) 0xde;
495 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
497 if ((_Write((char *)&msg
, sizeof(msg
))) < sizeof(msg
))
511 # pragma warning(default: 4310)
512 #endif // __VISUALC__
515 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, wxUint32 nbytes
)
518 Pushback(buffer
, nbytes
);
526 wxSocketBase
& wxSocketBase::Discard()
529 char *my_data
= new char[MAX_DISCARD_SIZE
];
530 wxUint32 recv_size
= MAX_DISCARD_SIZE
;
537 SetFlags(wxSOCKET_NOWAIT
);
539 while (recv_size
== MAX_DISCARD_SIZE
)
541 recv_size
= _Read(my_data
, MAX_DISCARD_SIZE
);
549 // Allow read events again
555 // --------------------------------------------------------------
556 // wxSocketBase get local or peer addresses
557 // --------------------------------------------------------------
559 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
566 peer
= GSocket_GetPeer(m_socket
);
567 addr_man
.SetAddress(peer
);
568 GAddress_destroy(peer
);
573 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
580 local
= GSocket_GetLocal(m_socket
);
581 addr_man
.SetAddress(local
);
582 GAddress_destroy(local
);
587 // --------------------------------------------------------------
588 // wxSocketBase save and restore socket state
589 // --------------------------------------------------------------
591 void wxSocketBase::SaveState()
593 wxSocketState
*state
;
595 state
= new wxSocketState();
597 state
->m_notify_state
= m_notify_state
;
598 state
->m_neededreq
= m_neededreq
;
599 state
->m_flags
= m_flags
;
600 state
->m_cbk
= m_cbk
;
601 state
->m_cdata
= m_cdata
;
603 m_states
.Append(state
);
606 void wxSocketBase::RestoreState()
609 wxSocketState
*state
;
611 node
= m_states
.Last();
615 state
= (wxSocketState
*)node
->Data();
617 SetFlags(state
->m_flags
);
618 m_cbk
= state
->m_cbk
;
619 m_cdata
= state
->m_cdata
;
620 m_neededreq
= state
->m_neededreq
;
621 Notify(state
->m_notify_state
);
628 // --------------------------------------------------------------
629 // wxSocketBase Wait functions
630 // --------------------------------------------------------------
632 // GRG: I have completely rewritten this family of functions
633 // so that they don't depend on event notifications; instead,
634 // they poll the socket, using GSocket_Select(), to check for
635 // the specified combination of event flags, until an event
636 // occurs or until the timeout ellapses. The polling loop
637 // calls PROCESS_EVENTS(), so this won't block the GUI.
639 bool wxSocketBase::_Wait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
641 GSocketEventFlags result
;
642 _wxSocketInternalTimer timer
;
646 // Set this to TRUE to interrupt ongoing waits
649 // Check for valid socket
653 // If it is not a server, it must be connected or establishing connection
654 if ((m_type
!= SOCK_SERVER
) && (!m_connected
&& !m_establishing
))
657 // Check for valid timeout value
659 timeout
= seconds
* 1000 + milliseconds
;
661 timeout
= m_timeout
* 1000;
666 timer
.m_state
= &state
;
668 timer
.Start((int)timeout
, TRUE
);
671 // Active polling (without using events)
673 // NOTE: this duplicates some of the code in OnRequest (lost
674 // connection and connection establishment handling) but this
675 // doesn't hurt. It has to be here because the event might
676 // be a bit delayed, and it has to be in OnRequest as well
677 // because maybe the WaitXXX functions are not being used.
679 // Do this at least once (important if timeout == 0, when
680 // we are just polling)
684 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
687 if (result
& GSOCK_LOST_FLAG
)
694 // Incoming connection (server) or connection established (client)
695 if (result
& GSOCK_CONNECTION_FLAG
)
699 m_establishing
= FALSE
;
703 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
710 if ((timeout
== 0) || (m_interrupt
))
720 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
722 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
724 GSOCK_CONNECTION_FLAG
|
728 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
730 // Check pushback buffer
734 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
);
737 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
739 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
742 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
744 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
747 void wxSocketBase::SetTimeout(long seconds
)
752 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
755 // --------------------------------------------------------------
756 // wxSocketBase flags
757 // --------------------------------------------------------------
759 void wxSocketBase::SetFlags(wxSockFlags _flags
)
764 // --------------------------------------------------------------
765 // wxSocketBase callback management
766 // --------------------------------------------------------------
768 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
770 wxSockCbk old_cbk
= cbk_
;
776 char *wxSocketBase::CallbackData(char *data
)
778 char *old_data
= m_cdata
;
784 // --------------------------------------------------------------
785 // wxSocketBase automatic notifier
786 // --------------------------------------------------------------
788 // All events (INPUT, OUTPUT, CONNECTION, LOST) are now always
789 // internally watched; but users will only be notified of those
790 // events they are interested in.
792 static void LINKAGEMODE
wx_socket_callback(GSocket
* WXUNUSED(socket
),
793 GSocketEvent event
, char *cdata
)
795 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
797 sckobj
->OnRequest((wxSocketNotify
)event
);
800 wxSocketEventFlags
wxSocketBase::EventToNotify(wxSocketNotify evt
)
804 case GSOCK_INPUT
: return GSOCK_INPUT_FLAG
;
805 case GSOCK_OUTPUT
: return GSOCK_OUTPUT_FLAG
;
806 case GSOCK_CONNECTION
: return GSOCK_CONNECTION_FLAG
;
807 case GSOCK_LOST
: return GSOCK_LOST_FLAG
;
812 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
817 void wxSocketBase::Notify(bool notify
)
819 m_notify_state
= notify
;
822 void wxSocketBase::OnRequest(wxSocketNotify req_evt
)
824 wxSocketEvent
event(m_id
);
825 wxSocketEventFlags flag
= EventToNotify(req_evt
);
827 // fprintf(stderr, "%s: Entering OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
829 // NOTE: this duplicates some of the code in _Wait, (lost
830 // connections and delayed connection establishment) but
831 // this doesn't hurt. It has to be here because maybe the
832 // WaitXXX are not being used, and it has to be in _Wait
833 // as well because the event might be a bit delayed.
837 case wxSOCKET_CONNECTION
:
838 m_establishing
= FALSE
;
845 // If we are in the middle of a R/W operation, do not
846 // propagate events to users.
849 if (m_reading
) return;
851 case wxSOCKET_OUTPUT
:
852 if (m_writing
) return;
855 if (((m_neededreq
& flag
) == flag
) && m_notify_state
)
857 // fprintf(stderr, "%s: Evt %d delivered\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
858 event
.m_socket
= this;
859 event
.m_skevt
= req_evt
;
862 #if EXPERIMENTAL_USE_POST
863 wxPostEvent(m_evt_handler
, event
);
868 OldOnNotify(req_evt
);
870 m_cbk(*this, req_evt
, m_cdata
);
874 // fprintf(stderr, "%s: Exiting OnRequest (evt %d)\n", (m_type == SOCK_CLIENT)? "client" : "server", req_evt);
877 void wxSocketBase::OldOnNotify(wxSocketNotify
WXUNUSED(evt
))
881 // --------------------------------------------------------------
882 // wxSocketBase set event handler
883 // --------------------------------------------------------------
885 void wxSocketBase::SetEventHandler(wxEvtHandler
& h_evt
, int id
)
887 m_evt_handler
= &h_evt
;
890 SetNextHandler(&h_evt
);
893 // --------------------------------------------------------------
894 // wxSocketBase pushback
895 // --------------------------------------------------------------
897 void wxSocketBase::Pushback(const char *buffer
, wxUint32 size
)
901 if (m_unread
== NULL
)
902 m_unread
= (char *)malloc(size
);
907 tmp
= (char *)malloc(m_unrd_size
+ size
);
908 memcpy(tmp
+size
, m_unread
, m_unrd_size
);
916 memcpy(m_unread
, buffer
, size
);
919 wxUint32
wxSocketBase::GetPushback(char *buffer
, wxUint32 size
, bool peek
)
924 if (size
> (m_unrd_size
-m_unrd_cur
))
925 size
= m_unrd_size
-m_unrd_cur
;
927 memcpy(buffer
, (m_unread
+m_unrd_cur
), size
);
932 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
* 1000);
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
* 1000);
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
);
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 // --------------------------------------------------------------
1055 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1062 // This should never happen.
1064 GSocket_destroy(m_socket
);
1066 // Initialize all socket stuff ...
1067 m_socket
= GSocket_new();
1068 m_connected
= FALSE
;
1069 m_establishing
= FALSE
;
1074 GSocket_SetTimeout(m_socket
, m_timeout
* 1000);
1075 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1076 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1077 wx_socket_callback
, (char *)this);
1079 // GRG: If wait == FALSE, then the call should be nonblocking.
1080 // When we are finished, we put the socket to blocking mode
1084 GSocket_SetNonBlocking(m_socket
, TRUE
);
1086 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1087 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1090 GSocket_SetNonBlocking(m_socket
, FALSE
);
1092 if (err
!= GSOCK_NOERROR
)
1094 if (err
== GSOCK_WOULDBLOCK
)
1095 m_establishing
= TRUE
;
1104 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1106 if (m_connected
) // Already connected
1109 if (!m_establishing
|| !m_socket
) // No connection in progress
1112 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1115 // --------------------------------------------------------------
1117 // --------------------------------------------------------------
1119 /* NOTE: experimental stuff - might change */
1121 wxDatagramSocket::wxDatagramSocket( wxSockAddress
& addr
, wxSockFlags flags
)
1122 : wxSocketBase( flags
, SOCK_DATAGRAM
)
1124 // Create the socket
1125 m_socket
= GSocket_new();
1130 // Setup the socket as non connection oriented
1131 GSocket_SetLocal(m_socket
, addr
.GetAddress());
1132 if( GSocket_SetNonOriented(m_socket
) != GSOCK_NOERROR
)
1134 GSocket_destroy(m_socket
);
1139 // Initialize all stuff
1140 m_connected
= FALSE
;
1141 m_establishing
= FALSE
;
1142 GSocket_SetTimeout( m_socket
, m_timeout
);
1143 GSocket_SetCallback( m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1144 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1145 wx_socket_callback
, (char*)this );
1149 wxDatagramSocket
& wxDatagramSocket::RecvFrom( wxSockAddress
& addr
,
1158 wxDatagramSocket
& wxDatagramSocket::SendTo( wxSockAddress
& addr
,
1162 GSocket_SetPeer(m_socket
, addr
.GetAddress());
1167 // --------------------------------------------------------------
1169 // --------------------------------------------------------------
1171 wxSocketEvent::wxSocketEvent(int id
)
1174 wxEventType type
= (wxEventType
)wxEVT_SOCKET
;
1179 void wxSocketEvent::CopyObject(wxObject
& obj_d
) const
1181 wxSocketEvent
*event
= (wxSocketEvent
*)&obj_d
;
1183 wxEvent::CopyObject(obj_d
);
1185 event
->m_skevt
= m_skevt
;
1186 event
->m_socket
= m_socket
;
1189 // --------------------------------------------------------------------------
1191 // --------------------------------------------------------------------------
1193 class WXDLLEXPORT wxSocketModule
: public wxModule
1195 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1199 return GSocket_Init();
1207 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)