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 /////////////////////////////////////////////////////////////////////////////
30 #include "wx/object.h"
31 #include "wx/string.h"
34 #include "wx/module.h"
41 /////////////////////////////////////////////////////////////////////////////
43 /////////////////////////////////////////////////////////////////////////////
44 #include "wx/sckaddr.h"
45 #include "wx/socket.h"
47 // --------------------------------------------------------------
49 // --------------------------------------------------------------
50 #if !USE_SHARED_LIBRARY
51 IMPLEMENT_CLASS(wxSocketBase
, wxObject
)
52 IMPLEMENT_CLASS(wxSocketServer
, wxSocketBase
)
53 IMPLEMENT_CLASS(wxSocketClient
, wxSocketBase
)
54 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent
, wxEvent
)
57 class wxSocketState
: public wxObject
61 GSocketEventFlags evt_notify_state
;
62 wxSocketBase::wxSockFlags socket_flags
;
63 wxSocketBase::wxSockCbk c_callback
;
64 char *c_callback_data
;
67 wxSocketState() : wxObject() {}
70 // --------------------------------------------------------------
71 // wxSocketBase ctor and dtor
72 // --------------------------------------------------------------
74 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags
,
75 wxSocketBase::wxSockType _type
) :
77 m_socket(NULL
), m_flags(_flags
), m_type(_type
),
79 m_lcount(0), m_timeout(600),
80 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
81 m_cbk(NULL
), m_cdata(NULL
),
82 m_connected(FALSE
), m_establishing(FALSE
),
83 m_notify_state(FALSE
), m_id(-1),
84 m_defering(NO_DEFER
), m_error(FALSE
),
89 wxSocketBase::wxSocketBase() :
91 m_socket(NULL
), m_flags(WAITALL
| SPEED
), m_type(SOCK_UNINIT
),
93 m_lcount(0), m_timeout(600),
94 m_unread(NULL
), m_unrd_size(0), m_unrd_cur(0),
95 m_cbk(NULL
), m_cdata(NULL
),
96 m_connected(FALSE
), m_establishing(FALSE
),
97 m_notify_state(FALSE
), m_id(-1),
98 m_defering(NO_DEFER
), m_error(FALSE
),
103 wxSocketBase::~wxSocketBase()
108 // Shutdown and close the socket
111 // Destroy the GSocket object
113 GSocket_destroy(m_socket
);
116 bool wxSocketBase::Close()
121 GSocket_UnsetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
122 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
);
124 // Shutdown the connection
125 GSocket_Shutdown(m_socket
);
127 m_establishing
= FALSE
;
133 // --------------------------------------------------------------
134 // wxSocketBase basic IO operations
135 // --------------------------------------------------------------
137 // GRG: I have made some changes to wxSocket internal event
138 // system; now, all events (INPUT, OUTPUT, CONNECTION, LOST)
139 // are always internally monitored; but users will only be
140 // notified of these events they are interested in. So we
141 // no longer have to change the event mask with SetNotify()
142 // in internal functions like DeferRead, DeferWrite, and
143 // the like. This solves a lot of problems.
145 // GRG: I added m_error handling to IO operations. Now,
146 // wxSocketBase::Error() correctly indicates if the last
147 // operation from {Read, Write, ReadMsg, WriteMsg, Peek,
148 // Unread, Discard} failed. Note that now, every function
149 // that updates m_lcount, also updates m_error. While I
150 // was at it, also fixed an UGLY bug in ReadMsg.
152 class _wxSocketInternalTimer
: public wxTimer
156 unsigned long m_new_val
;
160 *m_state
= m_new_val
; // Change the value
164 int wxSocketBase::DeferRead(char *buffer
, wxUint32 nbytes
)
167 _wxSocketInternalTimer timer
;
169 wxASSERT(m_defering
== NO_DEFER
);
171 // Set the defering mode to READ.
172 m_defering
= DEFER_READ
;
174 // Set the current buffer.
175 m_defer_buffer
= buffer
;
176 m_defer_nbytes
= nbytes
;
177 m_defer_timer
= &timer
;
179 timer
.m_state
= (int *)&m_defer_buffer
;
182 timer
.Start(m_timeout
* 1000, FALSE
);
184 // If the socket is readable, call DoDefer for the first time
185 if (GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
))
188 // Wait for buffer completion.
189 while (m_defer_buffer
!= NULL
)
194 // Disable defering mode.
195 m_defering
= NO_DEFER
;
196 m_defer_timer
= NULL
;
198 // Return the number of bytes read from the socket.
199 return nbytes
-m_defer_nbytes
;
202 wxSocketBase
& wxSocketBase::Read(char* buffer
, wxUint32 nbytes
)
208 // we try this even if the connection has already been closed.
209 m_lcount
= GetPushback(buffer
, nbytes
, FALSE
);
213 if (!m_connected
|| !m_socket
)
215 // if no data retrieved AND not connected, it is an error.
222 // If we have got the whole needed buffer, return immediately
226 // Possible combinations (they are checked in this order)
233 if (m_flags
& NOWAIT
) // NOWAIT
235 GSocket_SetNonBlocking(m_socket
, TRUE
);
236 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
237 GSocket_SetNonBlocking(m_socket
, FALSE
);
242 else if (m_flags
& SPEED
& WAITALL
) // SPEED, WAITALL
244 while (ret
> 0 && nbytes
> 0)
246 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
251 // In case the last call was an error ...
255 else if (m_flags
& SPEED
) // SPEED, !WAITALL
257 ret
= GSocket_Read(m_socket
, buffer
, nbytes
);
262 else // NONE or WAITALL
264 ret
= DeferRead(buffer
, nbytes
);
270 // If we have read some data, then it is not an error, even
271 // when in WAITALL mode, the last low-level IO call might
279 wxSocketBase
& wxSocketBase::ReadMsg(char* buffer
, wxUint32 nbytes
)
281 #define MAX_BUFSIZE (10 * 1024)
284 unsigned long len
, len2
, sig
;
291 // sig should be an explicit 32-bit unsigned integer; I've seen
292 // compilers in which wxUint32 was actually a 16-bit unsigned integer
295 SetFlags(old_flags
| WAITALL
);
297 Read((char *)&msg
, sizeof(msg
));
298 if (m_lcount
!= sizeof(msg
))
305 sig
= msg
.sig
[0] & 0xff;
306 sig
|= (wxUint32
)(msg
.sig
[1] & 0xff) << 8;
307 sig
|= (wxUint32
)(msg
.sig
[2] & 0xff) << 16;
308 sig
|= (wxUint32
)(msg
.sig
[3] & 0xff) << 24;
310 if (sig
!= 0xfeeddead)
312 wxLogDebug(_T("Warning: invalid signature returned to ReadMsg\n"));
318 len
= msg
.len
[0] & 0xff;
319 len
|= (wxUint32
)(msg
.len
[1] & 0xff) << 8;
320 len
|= (wxUint32
)(msg
.len
[2] & 0xff) << 16;
321 len
|= (wxUint32
)(msg
.len
[3] & 0xff) << 24;
331 // The "len &&" in the following statements is necessary so
332 // that we don't attempt to read (and possibly hang the system)
333 // if the message was zero bytes long
334 if (len
&& Read(buffer
, len
).LastCount() != len
)
342 char *discard_buffer
= new char[MAX_BUFSIZE
];
347 discard_len
= ((len2
> MAX_BUFSIZE
)? MAX_BUFSIZE
: len2
);
348 discard_len
= Read(discard_buffer
, discard_len
).LastCount();
351 while ((discard_len
> 0) && len2
);
353 delete [] discard_buffer
;
362 if (Read((char *)&msg
, sizeof(msg
)).LastCount() != sizeof(msg
))
369 sig
= msg
.sig
[0] & 0xff;
370 sig
|= (wxUint32
)(msg
.sig
[1] & 0xff) << 8;
371 sig
|= (wxUint32
)(msg
.sig
[2] & 0xff) << 16;
372 sig
|= (wxUint32
)(msg
.sig
[3] & 0xff) << 24;
374 if (sig
!= 0xdeadfeed)
377 wxLogDebug(_T("Warning: invalid signature returned to ReadMsg\n"));
386 wxSocketBase
& wxSocketBase::Peek(char* buffer
, wxUint32 nbytes
)
388 Read(buffer
, nbytes
);
389 CreatePushbackAfter(buffer
, nbytes
);
394 int wxSocketBase::DeferWrite(const char *buffer
, wxUint32 nbytes
)
397 _wxSocketInternalTimer timer
;
399 wxASSERT(m_defering
== NO_DEFER
);
401 m_defering
= DEFER_WRITE
;
403 // Set the current buffer
404 m_defer_buffer
= (char *)buffer
;
405 m_defer_nbytes
= nbytes
;
406 m_defer_timer
= &timer
;
409 timer
.m_state
= (int *)&m_defer_buffer
;
412 timer
.Start(m_timeout
* 1000, FALSE
);
414 // If the socket is writable, call DoDefer for the first time
415 if (GSocket_Select(m_socket
, GSOCK_OUTPUT_FLAG
))
418 // Wait for buffer completion.
419 while (m_defer_buffer
!= NULL
)
423 m_defer_timer
= NULL
;
426 m_defering
= NO_DEFER
;
428 return nbytes
-m_defer_nbytes
;
431 wxSocketBase
& wxSocketBase::Write(const char *buffer
, wxUint32 nbytes
)
438 if (!m_connected
|| !m_socket
)
444 // Possible combinations (they are checked in this order)
451 if (m_flags
& NOWAIT
) // NOWAIT
453 GSocket_SetNonBlocking(m_socket
, TRUE
);
454 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
455 GSocket_SetNonBlocking(m_socket
, FALSE
);
460 else if (m_flags
& SPEED
& WAITALL
) // SPEED, WAITALL
462 while (ret
> 0 && nbytes
> 0)
464 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
469 // In case the last call was an error ...
473 else if (m_flags
& SPEED
) // SPEED, !WAITALL
475 ret
= GSocket_Write(m_socket
, buffer
, nbytes
);
480 else // NONE or WAITALL
482 ret
= DeferWrite(buffer
, nbytes
);
488 // If we have written some data, then it is not an error,
489 // even when in WAITALL mode, the last low-level IO call
490 // might have failed.
497 wxSocketBase
& wxSocketBase::WriteMsg(const char *buffer
, wxUint32 nbytes
)
505 // warning about 'cast truncates constant value'
507 #pragma warning(disable: 4310)
508 #endif // __VISUALC__
510 msg
.sig
[0] = (char) 0xad;
511 msg
.sig
[1] = (char) 0xde;
512 msg
.sig
[2] = (char) 0xed;
513 msg
.sig
[3] = (char) 0xfe;
515 msg
.len
[0] = (char) nbytes
& 0xff;
516 msg
.len
[1] = (char) (nbytes
>> 8) & 0xff;
517 msg
.len
[2] = (char) (nbytes
>> 16) & 0xff;
518 msg
.len
[3] = (char) (nbytes
>> 24) & 0xff;
521 SetFlags(old_flags
| WAITALL
);
523 if (Write((char *)&msg
, sizeof(msg
)).LastCount() < sizeof(msg
))
529 if (Write(buffer
, nbytes
).LastCount() < nbytes
)
536 msg
.sig
[0] = (char) 0xed;
537 msg
.sig
[1] = (char) 0xfe;
538 msg
.sig
[2] = (char) 0xad;
539 msg
.sig
[3] = (char) 0xde;
540 msg
.len
[0] = msg
.len
[1] = msg
.len
[2] = msg
.len
[3] = (char) 0;
542 if (Write((char *)&msg
, sizeof(msg
)).LastCount() < sizeof(msg
))
549 #pragma warning(default: 4310)
550 #endif // __VISUALC__
553 wxSocketBase
& wxSocketBase::Unread(const char *buffer
, wxUint32 nbytes
)
560 CreatePushbackAfter(buffer
, nbytes
);
566 bool wxSocketBase::IsData() const
571 return (GSocket_Select(m_socket
, GSOCK_INPUT_FLAG
));
574 // GRG: DoDefer() no longer needs to know which event occured,
575 // because this was only used to catch LOST events and set
576 // m_defer_buffer = NULL; this is done in OnRequest() now.
578 void wxSocketBase::DoDefer()
588 ret
= GSocket_Read(m_socket
, m_defer_buffer
, m_defer_nbytes
);
591 ret
= GSocket_Write(m_socket
, m_defer_buffer
, m_defer_nbytes
);
599 m_defer_nbytes
-= ret
;
601 // If we are waiting for all bytes to be acquired, keep the defering
603 if ((m_flags
& WAITALL
) == 0 || m_defer_nbytes
== 0 || ret
< 0)
605 m_defer_buffer
= NULL
;
609 m_defer_buffer
+= ret
;
610 m_defer_timer
->Start(m_timeout
* 1000, FALSE
);
614 void wxSocketBase::Discard()
616 #define MAX_BUFSIZE (10*1024)
618 char *my_data
= new char[MAX_BUFSIZE
];
619 wxUint32 recv_size
= MAX_BUFSIZE
;
623 SetFlags(NOWAIT
); // GRG: SPEED was not needed here!
625 while (recv_size
== MAX_BUFSIZE
)
627 recv_size
= Read(my_data
, MAX_BUFSIZE
).LastCount();
640 // --------------------------------------------------------------
641 // wxSocketBase get local or peer addresses
642 // --------------------------------------------------------------
644 bool wxSocketBase::GetPeer(wxSockAddress
& addr_man
) const
651 peer
= GSocket_GetPeer(m_socket
);
652 addr_man
.SetAddress(peer
);
653 GAddress_destroy(peer
);
658 bool wxSocketBase::GetLocal(wxSockAddress
& addr_man
) const
665 local
= GSocket_GetLocal(m_socket
);
666 addr_man
.SetAddress(local
);
667 GAddress_destroy(local
);
672 // --------------------------------------------------------------
673 // wxSocketBase save and restore socket state
674 // --------------------------------------------------------------
676 void wxSocketBase::SaveState()
678 wxSocketState
*state
;
680 state
= new wxSocketState();
682 state
->notify_state
= m_notify_state
;
683 state
->evt_notify_state
= m_neededreq
;
684 state
->socket_flags
= m_flags
;
685 state
->c_callback
= m_cbk
;
686 state
->c_callback_data
= m_cdata
;
688 m_states
.Append(state
);
691 void wxSocketBase::RestoreState()
694 wxSocketState
*state
;
696 node
= m_states
.Last();
700 state
= (wxSocketState
*)node
->Data();
702 SetFlags(state
->socket_flags
);
703 m_neededreq
= state
->evt_notify_state
;
704 m_cbk
= state
->c_callback
;
705 m_cdata
= state
->c_callback_data
;
706 Notify(state
->notify_state
);
713 // --------------------------------------------------------------
714 // wxSocketBase Wait functions
715 // --------------------------------------------------------------
717 // GRG: I have completely rewritten this family of functions
718 // so that they don't depend on event notifications; instead,
719 // they poll the socket, using GSocket_Select(), to check for
720 // the specified combination of event flags, until an event
721 // occurs or until the timeout ellapses. The polling loop
722 // calls wxYield(), so this won't block the GUI.
724 bool wxSocketBase::_Wait(long seconds
, long milliseconds
, wxSocketEventFlags flags
)
726 GSocketEventFlags result
;
727 _wxSocketInternalTimer timer
;
731 // Check for valid socket
735 // If it is not a server, it must be connected or establishing connection
736 if ((m_type
!= SOCK_SERVER
) && (!m_connected
&& !m_establishing
))
739 // Check for valid timeout value
741 timeout
= seconds
* 1000 + milliseconds
;
743 timeout
= m_timeout
* 1000;
746 timer
.m_state
= &state
;
748 timer
.Start(timeout
, TRUE
);
750 // Active polling (without using events)
752 // NOTE: this duplicates some of the code in OnRequest (lost
753 // connection and connection establishment handling) but this
754 // doesn't hurt. It has to be here because the event might
755 // be a bit delayed, and it has to be in OnRequest as well
756 // because maybe the WaitXXX functions are not being used.
760 result
= GSocket_Select(m_socket
, flags
| GSOCK_LOST_FLAG
);
763 if (result
& GSOCK_LOST_FLAG
)
766 m_defer_buffer
= NULL
;
771 // Incoming connection (server) or connection established (client)
772 if (result
& GSOCK_CONNECTION_FLAG
)
776 m_establishing
= FALSE
;
780 // If we are in the middle of a deferred R/W, ignore these.
781 if ((result
& GSOCK_INPUT_FLAG
) || (result
& GSOCK_OUTPUT_FLAG
))
783 if (m_defer_buffer
== NULL
)
797 bool wxSocketBase::Wait(long seconds
, long milliseconds
)
799 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
|
801 GSOCK_CONNECTION_FLAG
|
805 bool wxSocketBase::WaitForRead(long seconds
, long milliseconds
)
807 return _Wait(seconds
, milliseconds
, GSOCK_INPUT_FLAG
);
810 bool wxSocketBase::WaitForWrite(long seconds
, long milliseconds
)
812 return _Wait(seconds
, milliseconds
, GSOCK_OUTPUT_FLAG
);
815 bool wxSocketBase::WaitForLost(long seconds
, long milliseconds
)
817 return _Wait(seconds
, milliseconds
, GSOCK_LOST_FLAG
);
820 void wxSocketBase::SetTimeout(long seconds
)
825 GSocket_SetTimeout(m_socket
, m_timeout
);
828 // --------------------------------------------------------------
829 // wxSocketBase flags
830 // --------------------------------------------------------------
832 void wxSocketBase::SetFlags(wxSockFlags _flags
)
837 wxSocketBase::wxSockFlags
wxSocketBase::GetFlags() const
842 // --------------------------------------------------------------
843 // wxSocketBase callback management
844 // --------------------------------------------------------------
846 wxSocketBase::wxSockCbk
wxSocketBase::Callback(wxSockCbk cbk_
)
848 wxSockCbk old_cbk
= cbk_
;
854 char *wxSocketBase::CallbackData(char *data
)
856 char *old_data
= m_cdata
;
862 // --------------------------------------------------------------
863 // wxSocketBase automatic notifier
864 // --------------------------------------------------------------
866 static void LINKAGEMODE
wx_socket_callback(GSocket
*socket
, GSocketEvent event
, char *cdata
)
868 wxSocketBase
*sckobj
= (wxSocketBase
*)cdata
;
870 sckobj
->OnRequest((wxSocketNotify
)event
);
873 wxSocketEventFlags
wxSocketBase::EventToNotify(wxSocketNotify evt
)
877 case GSOCK_INPUT
: return GSOCK_INPUT_FLAG
;
878 case GSOCK_OUTPUT
: return GSOCK_OUTPUT_FLAG
;
879 case GSOCK_CONNECTION
: return GSOCK_CONNECTION_FLAG
;
880 case GSOCK_LOST
: return GSOCK_LOST_FLAG
;
885 void wxSocketBase::SetNotify(wxSocketEventFlags flags
)
890 void wxSocketBase::Notify(bool notify
)
892 m_notify_state
= notify
;
895 void wxSocketBase::OnRequest(wxSocketNotify req_evt
)
897 wxSocketEvent
event(m_id
);
898 wxSocketEventFlags flag
= EventToNotify(req_evt
);
900 // NOTE: this duplicates some of the code in _Wait (lost
901 // connection and connection establishment handling) but
902 // this doesn't hurt. It has to be here because maybe the
903 // WaitXXX are not being used, and it has to be in _Wait
904 // as well because the event might be a bit delayed.
908 case wxSOCKET_CONNECTION
:
909 m_establishing
= FALSE
;
913 m_defer_buffer
= NULL
;
917 case wxSOCKET_OUTPUT
:
920 // GRG: DoDefer() no longer needs to know which
921 // event occured, because this was only used to
922 // catch LOST events and set m_defer_buffer to
923 // NULL, and this is done in OnRequest() now.
925 // Do not notify to user
931 if (((m_neededreq
& flag
) == flag
) && m_notify_state
)
933 event
.m_socket
= this;
934 event
.m_skevt
= req_evt
;
936 OldOnNotify(req_evt
);
939 m_cbk(*this, req_evt
, m_cdata
);
943 void wxSocketBase::OldOnNotify(wxSocketNotify evt
)
947 // --------------------------------------------------------------
948 // wxSocketBase set event handler
949 // --------------------------------------------------------------
951 void wxSocketBase::SetEventHandler(wxEvtHandler
& h_evt
, int id
)
953 SetNextHandler(&h_evt
);
957 // --------------------------------------------------------------
958 // wxSocketBase pushback library
959 // --------------------------------------------------------------
961 void wxSocketBase::CreatePushbackAfter(const char *buffer
, wxUint32 size
)
965 if (m_unread
!= NULL
)
966 m_unread
= (char *) realloc(m_unread
, m_unrd_size
+size
);
968 m_unread
= (char *) malloc(size
);
970 curr_pos
= m_unread
+ m_unrd_size
;
972 memcpy(curr_pos
, buffer
, size
);
976 void wxSocketBase::CreatePushbackBefore(const char *buffer
, wxUint32 size
)
978 if (m_unread
== NULL
)
979 m_unread
= (char *)malloc(size
);
983 tmp
= (char *)malloc(m_unrd_size
+ size
);
984 memcpy(tmp
+size
, m_unread
, m_unrd_size
);
992 memcpy(m_unread
, buffer
, size
);
995 wxUint32
wxSocketBase::GetPushback(char *buffer
, wxUint32 size
, bool peek
)
1000 if (size
> (m_unrd_size
-m_unrd_cur
))
1001 size
= m_unrd_size
-m_unrd_cur
;
1002 memcpy(buffer
, (m_unread
+m_unrd_cur
), size
);
1006 if (m_unrd_size
== m_unrd_cur
) {
1017 // --------------------------------------------------------------
1019 // --------------------------------------------------------------
1021 // --------------------------------------------------------------
1022 // wxSocketServer ctor and dtor
1023 // --------------------------------------------------------------
1025 wxSocketServer::wxSocketServer(wxSockAddress
& addr_man
,
1026 wxSockFlags flags
) :
1027 wxSocketBase(flags
, SOCK_SERVER
)
1029 // Create the socket
1030 m_socket
= GSocket_new();
1035 // Setup the socket as server
1036 GSocket_SetLocal(m_socket
, addr_man
.GetAddress());
1037 if (GSocket_SetServer(m_socket
) != GSOCK_NOERROR
)
1039 GSocket_destroy(m_socket
);
1044 GSocket_SetTimeout(m_socket
, m_timeout
);
1045 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1046 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1047 wx_socket_callback
, (char *)this);
1051 // --------------------------------------------------------------
1052 // wxSocketServer Accept
1053 // --------------------------------------------------------------
1055 bool wxSocketServer::AcceptWith(wxSocketBase
& sock
, bool wait
)
1057 GSocket
*child_socket
;
1062 // GRG: If wait == FALSE, then the call should be nonblocking.
1063 // When we are finished, we put the socket to blocking mode
1067 GSocket_SetNonBlocking(m_socket
, TRUE
);
1069 child_socket
= GSocket_WaitConnection(m_socket
);
1072 GSocket_SetNonBlocking(m_socket
, FALSE
);
1074 // GRG: this was not being handled!
1075 if (child_socket
== NULL
)
1078 sock
.m_type
= SOCK_INTERNAL
;
1079 sock
.m_socket
= child_socket
;
1080 sock
.m_connected
= TRUE
;
1082 GSocket_SetTimeout(sock
.m_socket
, sock
.m_timeout
);
1083 GSocket_SetCallback(sock
.m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1084 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1085 wx_socket_callback
, (char *)&sock
);
1090 wxSocketBase
*wxSocketServer::Accept(bool wait
)
1092 wxSocketBase
* sock
= new wxSocketBase();
1094 sock
->SetFlags((wxSockFlags
)m_flags
);
1096 if (!AcceptWith(*sock
, wait
))
1102 bool wxSocketServer::WaitForAccept(long seconds
, long milliseconds
)
1104 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1107 // --------------------------------------------------------------
1109 // --------------------------------------------------------------
1111 // --------------------------------------------------------------
1112 // wxSocketClient ctor and dtor
1113 // --------------------------------------------------------------
1115 wxSocketClient::wxSocketClient(wxSockFlags _flags
) :
1116 wxSocketBase(_flags
, SOCK_CLIENT
)
1120 wxSocketClient::~wxSocketClient()
1124 // --------------------------------------------------------------
1125 // wxSocketClient Connect functions
1126 // --------------------------------------------------------------
1127 bool wxSocketClient::Connect(wxSockAddress
& addr_man
, bool wait
)
1134 // This should never happen.
1136 GSocket_destroy(m_socket
);
1138 // Initialize all socket stuff ...
1139 m_socket
= GSocket_new();
1140 m_connected
= FALSE
;
1141 m_establishing
= FALSE
;
1146 GSocket_SetTimeout(m_socket
, m_timeout
);
1148 // GRG: If wait == FALSE, then the call should be nonblocking.
1149 // When we are finished, we put the socket to blocking mode
1153 GSocket_SetNonBlocking(m_socket
, TRUE
);
1155 GSocket_SetPeer(m_socket
, addr_man
.GetAddress());
1156 err
= GSocket_Connect(m_socket
, GSOCK_STREAMED
);
1157 GSocket_SetCallback(m_socket
, GSOCK_INPUT_FLAG
| GSOCK_OUTPUT_FLAG
|
1158 GSOCK_LOST_FLAG
| GSOCK_CONNECTION_FLAG
,
1159 wx_socket_callback
, (char *)this);
1162 GSocket_SetNonBlocking(m_socket
, FALSE
);
1164 if (err
!= GSOCK_NOERROR
)
1166 if (err
== GSOCK_WOULDBLOCK
)
1167 m_establishing
= TRUE
;
1176 bool wxSocketClient::WaitOnConnect(long seconds
, long milliseconds
)
1178 if (m_connected
) // Already connected
1181 if (!m_establishing
|| !m_socket
) // No connection in progress
1184 return _Wait(seconds
, milliseconds
, GSOCK_CONNECTION_FLAG
);
1187 // --------------------------------------------------------------
1189 // --------------------------------------------------------------
1191 wxSocketEvent::wxSocketEvent(int id
)
1194 wxEventType type
= (wxEventType
)wxEVT_SOCKET
;
1199 void wxSocketEvent::CopyObject(wxObject
& obj_d
) const
1201 wxSocketEvent
*event
= (wxSocketEvent
*)&obj_d
;
1203 wxEvent::CopyObject(obj_d
);
1205 event
->m_skevt
= m_skevt
;
1206 event
->m_socket
= m_socket
;
1209 // --------------------------------------------------------------------------
1211 // --------------------------------------------------------------------------
1212 class WXDLLEXPORT wxSocketModule
: public wxModule
{
1213 DECLARE_DYNAMIC_CLASS(wxSocketModule
)
1216 return GSocket_Init();
1223 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule
, wxModule
)