1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket)
4 * Author: Guillermo Rodriguez Garcia <guille@iies.es>
5 * Purpose: GSocket main MSW file
7 * -------------------------------------------------------------------------
11 * PLEASE don't put C++ comments here - this is a C source file.
14 #ifndef __GSOCKET_STANDALONE__
18 #if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
20 #ifndef __GSOCKET_STANDALONE__
22 #include "wx/msw/gsockmsw.h"
23 #include "wx/gsocket.h"
25 #define INSTANCE wxGetInstance()
32 /* If not using wxWindows, a global var called hInst must
33 * be available and it must containt the app's instance
36 #define INSTANCE hInst
38 #endif /* __GSOCKET_STANDALONE__ */
48 /* if we use configure for MSW SOCKLEN_T will be already defined */
54 /* using FD_SET results in this warning */
55 #pragma warning(disable:4127) /* conditional expression is constant */
56 #endif /* Visual C++ */
58 #define CLASSNAME "_GSocket_Internal_Window_Class"
59 #define WINDOWNAME "_GSocket_Internal_Window_Name"
61 /* Maximum number of different GSocket objects at a given time.
62 * This value can be modified at will, but it CANNOT be greater
63 * than (0x7FFF - WM_USER + 1)
65 #define MAXSOCKETS 1024
67 #if (MAXSOCKETS > (0x7FFF - WM_USER + 1))
68 #error "MAXSOCKETS is too big!"
72 /* Global variables */
74 extern HINSTANCE INSTANCE
;
76 static CRITICAL_SECTION critical
;
77 static GSocket
* socketList
[MAXSOCKETS
];
78 static int firstAvailable
;
80 /* Global initializers */
88 /* Create internal window for event notifications */
90 winClass
.lpfnWndProc
= _GSocket_Internal_WinProc
;
91 winClass
.cbClsExtra
= 0;
92 winClass
.cbWndExtra
= 0;
93 winClass
.hInstance
= INSTANCE
;
94 winClass
.hIcon
= (HICON
) NULL
;
95 winClass
.hCursor
= (HCURSOR
) NULL
;
96 winClass
.hbrBackground
= (HBRUSH
) NULL
;
97 winClass
.lpszMenuName
= (LPCTSTR
) NULL
;
98 winClass
.lpszClassName
= CLASSNAME
;
100 RegisterClass(&winClass
);
101 hWin
= CreateWindow(CLASSNAME
,
104 (HWND
) NULL
, (HMENU
) NULL
, INSTANCE
, (LPVOID
) NULL
);
106 if (!hWin
) return FALSE
;
108 /* Initialize socket list */
109 InitializeCriticalSection(&critical
);
111 for (i
= 0; i
< MAXSOCKETS
; i
++)
113 socketList
[i
] = NULL
;
117 /* Initialize WinSocket */
118 return (WSAStartup((1 << 8) | 1, &wsaData
) == 0);
121 void GSocket_Cleanup()
123 /* Destroy internal window */
125 UnregisterClass(CLASSNAME
, INSTANCE
);
127 /* Delete critical section */
128 DeleteCriticalSection(&critical
);
130 /* Cleanup WinSocket */
134 /* Constructors / Destructors for GSocket */
136 GSocket
*GSocket_new()
141 if ((socket
= (GSocket
*) malloc(sizeof(GSocket
))) == NULL
)
144 socket
->m_fd
= INVALID_SOCKET
;
145 for (i
= 0; i
< GSOCK_MAX_EVENT
; i
++)
147 socket
->m_cbacks
[i
] = NULL
;
149 socket
->m_local
= NULL
;
150 socket
->m_peer
= NULL
;
151 socket
->m_error
= GSOCK_NOERROR
;
152 socket
->m_server
= FALSE
;
153 socket
->m_stream
= TRUE
;
154 socket
->m_non_blocking
= FALSE
;
155 socket
->m_timeout
.tv_sec
= 10 * 60; /* 10 minutes */
156 socket
->m_timeout
.tv_usec
= 0;
157 socket
->m_detected
= 0;
159 /* Allocate a new message number for this socket */
160 EnterCriticalSection(&critical
);
163 while (socketList
[i
] != NULL
)
165 i
= (i
+ 1) % MAXSOCKETS
;
167 if (i
== firstAvailable
) /* abort! */
170 LeaveCriticalSection(&critical
);
174 socketList
[i
] = socket
;
175 firstAvailable
= (i
+ 1) % MAXSOCKETS
;
176 socket
->m_msgnumber
= (i
+ WM_USER
);
178 LeaveCriticalSection(&critical
);
183 void GSocket_destroy(GSocket
*socket
)
185 assert(socket
!= NULL
);
187 /* Remove the socket from the list */
188 EnterCriticalSection(&critical
);
189 socketList
[(socket
->m_msgnumber
- WM_USER
)] = NULL
;
190 LeaveCriticalSection(&critical
);
192 /* Check that the socket is really shutdowned */
193 if (socket
->m_fd
!= INVALID_SOCKET
)
194 GSocket_Shutdown(socket
);
196 /* Destroy private addresses */
198 GAddress_destroy(socket
->m_local
);
201 GAddress_destroy(socket
->m_peer
);
203 /* Destroy the socket itself */
208 * Disallow further read/write operations on this socket, close
209 * the fd and disable all callbacks.
211 void GSocket_Shutdown(GSocket
*socket
)
215 assert(socket
!= NULL
);
217 /* If socket has been created, shutdown it */
218 if (socket
->m_fd
!= INVALID_SOCKET
)
220 shutdown(socket
->m_fd
, 2);
221 closesocket(socket
->m_fd
);
222 socket
->m_fd
= INVALID_SOCKET
;
225 /* Disable GUI callbacks */
226 for (evt
= 0; evt
< GSOCK_MAX_EVENT
; evt
++)
227 socket
->m_cbacks
[evt
] = NULL
;
229 socket
->m_detected
= GSOCK_LOST_FLAG
;
230 _GSocket_Disable_Events(socket
);
233 /* Address handling */
239 * Set or get the local or peer address for this socket. The 'set'
240 * functions return GSOCK_NOERROR on success, an error code otherwise.
241 * The 'get' functions return a pointer to a GAddress object on success,
242 * or NULL otherwise, in which case they set the error code of the
243 * corresponding GSocket.
246 * GSOCK_INVSOCK - the socket is not valid.
247 * GSOCK_INVADDR - the address is not valid.
249 GSocketError
GSocket_SetLocal(GSocket
*socket
, GAddress
*address
)
251 assert(socket
!= NULL
);
253 /* the socket must be initialized, or it must be a server */
254 if (socket
->m_fd
!= INVALID_SOCKET
&& !socket
->m_server
)
256 socket
->m_error
= GSOCK_INVSOCK
;
257 return GSOCK_INVSOCK
;
261 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
263 socket
->m_error
= GSOCK_INVADDR
;
264 return GSOCK_INVADDR
;
268 GAddress_destroy(socket
->m_local
);
270 socket
->m_local
= GAddress_copy(address
);
272 return GSOCK_NOERROR
;
275 GSocketError
GSocket_SetPeer(GSocket
*socket
, GAddress
*address
)
277 assert(socket
!= NULL
);
280 if (address
== NULL
|| address
->m_family
== GSOCK_NOFAMILY
)
282 socket
->m_error
= GSOCK_INVADDR
;
283 return GSOCK_INVADDR
;
287 GAddress_destroy(socket
->m_peer
);
289 socket
->m_peer
= GAddress_copy(address
);
291 return GSOCK_NOERROR
;
294 GAddress
*GSocket_GetLocal(GSocket
*socket
)
297 struct sockaddr addr
;
298 SOCKLEN_T size
= sizeof(addr
);
301 assert(socket
!= NULL
);
303 /* try to get it from the m_local var first */
305 return GAddress_copy(socket
->m_local
);
307 /* else, if the socket is initialized, try getsockname */
308 if (socket
->m_fd
== INVALID_SOCKET
)
310 socket
->m_error
= GSOCK_INVSOCK
;
314 if (getsockname(socket
->m_fd
, &addr
, &size
) == SOCKET_ERROR
)
316 socket
->m_error
= GSOCK_IOERR
;
320 /* got a valid address from getsockname, create a GAddress object */
321 if ((address
= GAddress_new()) == NULL
)
323 socket
->m_error
= GSOCK_MEMERR
;
327 if ((err
= _GAddress_translate_from(address
, &addr
, size
)) != GSOCK_NOERROR
)
329 GAddress_destroy(address
);
330 socket
->m_error
= err
;
337 GAddress
*GSocket_GetPeer(GSocket
*socket
)
339 assert(socket
!= NULL
);
341 /* try to get it from the m_peer var */
343 return GAddress_copy(socket
->m_peer
);
348 /* Server specific parts */
350 /* GSocket_SetServer:
351 * Sets up this socket as a server. The local address must have been
352 * set with GSocket_SetLocal() before GSocket_SetServer() is called.
353 * Returns GSOCK_NOERROR on success, one of the following otherwise:
356 * GSOCK_INVSOCK - the socket is in use.
357 * GSOCK_INVADDR - the local address has not been set.
358 * GSOCK_IOERR - low-level error.
360 GSocketError
GSocket_SetServer(GSocket
*sck
)
366 /* must not be in use */
367 if (sck
->m_fd
!= INVALID_SOCKET
)
369 sck
->m_error
= GSOCK_INVSOCK
;
370 return GSOCK_INVSOCK
;
373 /* the local addr must have been set */
376 sck
->m_error
= GSOCK_INVADDR
;
377 return GSOCK_INVADDR
;
380 /* Initialize all fields */
381 sck
->m_server
= TRUE
;
382 sck
->m_stream
= TRUE
;
383 sck
->m_oriented
= TRUE
;
385 /* Create the socket */
386 sck
->m_fd
= socket(sck
->m_local
->m_realfamily
, SOCK_STREAM
, 0);
388 if (sck
->m_fd
== INVALID_SOCKET
)
390 sck
->m_error
= GSOCK_IOERR
;
394 ioctlsocket(sck
->m_fd
, FIONBIO
, (u_long FAR
*) &arg
);
395 _GSocket_Enable_Events(sck
);
397 /* Bind to the local address,
398 * retrieve the actual address bound,
399 * and listen up to 5 connections.
401 if ((bind(sck
->m_fd
, sck
->m_local
->m_addr
, sck
->m_local
->m_len
) != 0) ||
402 (getsockname(sck
->m_fd
,
403 sck
->m_local
->m_addr
,
404 (SOCKLEN_T
*)&sck
->m_local
->m_len
) != 0) ||
405 (listen(sck
->m_fd
, 5) != 0))
407 closesocket(sck
->m_fd
);
408 sck
->m_fd
= INVALID_SOCKET
;
409 sck
->m_error
= GSOCK_IOERR
;
413 return GSOCK_NOERROR
;
416 /* GSocket_WaitConnection:
417 * Waits for an incoming client connection. Returns a pointer to
418 * a GSocket object, or NULL if there was an error, in which case
419 * the last error field will be updated for the calling GSocket.
421 * Error codes (set in the calling GSocket)
422 * GSOCK_INVSOCK - the socket is not valid or not a server.
423 * GSOCK_TIMEDOUT - timeout, no incoming connections.
424 * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
425 * GSOCK_MEMERR - couldn't allocate memory.
426 * GSOCK_IOERR - low-level error.
428 GSocket
*GSocket_WaitConnection(GSocket
*sck
)
431 struct sockaddr from
;
432 SOCKLEN_T fromlen
= sizeof(from
);
438 /* Reenable CONNECTION events */
439 sck
->m_detected
&= ~GSOCK_CONNECTION_FLAG
;
441 /* If the socket has already been created, we exit immediately */
442 if (sck
->m_fd
== INVALID_SOCKET
|| !sck
->m_server
)
444 sck
->m_error
= GSOCK_INVSOCK
;
448 /* Create a GSocket object for the new connection */
449 connection
= GSocket_new();
453 sck
->m_error
= GSOCK_MEMERR
;
457 /* Wait for a connection (with timeout) */
458 if (_GSocket_Input_Timeout(sck
) == GSOCK_TIMEDOUT
)
460 GSocket_destroy(connection
);
461 /* sck->m_error set by _GSocket_Input_Timeout */
465 connection
->m_fd
= accept(sck
->m_fd
, &from
, &fromlen
);
467 if (connection
->m_fd
== INVALID_SOCKET
)
469 if (WSAGetLastError() == WSAEWOULDBLOCK
)
470 sck
->m_error
= GSOCK_WOULDBLOCK
;
472 sck
->m_error
= GSOCK_IOERR
;
474 GSocket_destroy(connection
);
478 /* Initialize all fields */
479 connection
->m_server
= FALSE
;
480 connection
->m_stream
= TRUE
;
481 connection
->m_oriented
= TRUE
;
483 /* Setup the peer address field */
484 connection
->m_peer
= GAddress_new();
485 if (!connection
->m_peer
)
487 GSocket_destroy(connection
);
488 sck
->m_error
= GSOCK_MEMERR
;
491 err
= _GAddress_translate_from(connection
->m_peer
, &from
, fromlen
);
492 if (err
!= GSOCK_NOERROR
)
494 GAddress_destroy(connection
->m_peer
);
495 GSocket_destroy(connection
);
500 ioctlsocket(connection
->m_fd
, FIONBIO
, (u_long FAR
*) &arg
);
501 _GSocket_Enable_Events(connection
);
506 /* Client specific parts */
509 * For stream (connection oriented) sockets, GSocket_Connect() tries
510 * to establish a client connection to a server using the peer address
511 * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
512 * connection has been succesfully established, or one of the error
513 * codes listed below. Note that for nonblocking sockets, a return
514 * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
515 * request can be completed later; you should use GSocket_Select()
516 * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
517 * corresponding asynchronous events.
519 * For datagram (non connection oriented) sockets, GSocket_Connect()
520 * just sets the peer address established with GSocket_SetPeer() as
521 * default destination.
524 * GSOCK_INVSOCK - the socket is in use or not valid.
525 * GSOCK_INVADDR - the peer address has not been established.
526 * GSOCK_TIMEDOUT - timeout, the connection failed.
527 * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
528 * GSOCK_MEMERR - couldn't allocate memory.
529 * GSOCK_IOERR - low-level error.
531 GSocketError
GSocket_Connect(GSocket
*sck
, GSocketStream stream
)
538 /* Enable CONNECTION events (needed for nonblocking connections) */
539 sck
->m_detected
&= ~GSOCK_CONNECTION_FLAG
;
541 if (sck
->m_fd
!= INVALID_SOCKET
)
543 sck
->m_error
= GSOCK_INVSOCK
;
544 return GSOCK_INVSOCK
;
549 sck
->m_error
= GSOCK_INVADDR
;
550 return GSOCK_INVADDR
;
553 /* Streamed or dgram socket? */
554 sck
->m_stream
= (stream
== GSOCK_STREAMED
);
555 sck
->m_oriented
= TRUE
;
556 sck
->m_server
= FALSE
;
558 /* Create the socket */
559 sck
->m_fd
= socket(sck
->m_peer
->m_realfamily
,
560 sck
->m_stream
? SOCK_STREAM
: SOCK_DGRAM
, 0);
562 if (sck
->m_fd
== INVALID_SOCKET
)
564 sck
->m_error
= GSOCK_IOERR
;
568 ioctlsocket(sck
->m_fd
, FIONBIO
, (u_long FAR
*) &arg
);
569 _GSocket_Enable_Events(sck
);
571 /* Connect it to the peer address, with a timeout (see below) */
572 ret
= connect(sck
->m_fd
, sck
->m_peer
->m_addr
, sck
->m_peer
->m_len
);
574 if (ret
== SOCKET_ERROR
)
576 err
= WSAGetLastError();
578 /* If connect failed with EWOULDBLOCK and the GSocket object
579 * is in blocking mode, we select() for the specified timeout
580 * checking for writability to see if the connection request
583 if ((err
== WSAEWOULDBLOCK
) && (!sck
->m_non_blocking
))
585 err
= _GSocket_Connect_Timeout(sck
);
587 if (err
!= GSOCK_NOERROR
)
589 closesocket(sck
->m_fd
);
590 sck
->m_fd
= INVALID_SOCKET
;
591 /* sck->m_error is set in _GSocket_Connect_Timeout */
597 /* If connect failed with EWOULDBLOCK and the GSocket object
598 * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
599 * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
600 * this way if the connection completes, a GSOCK_CONNECTION
601 * event will be generated, if enabled.
603 if ((err
== WSAEWOULDBLOCK
) && (sck
->m_non_blocking
))
605 sck
->m_error
= GSOCK_WOULDBLOCK
;
606 return GSOCK_WOULDBLOCK
;
609 /* If connect failed with an error other than EWOULDBLOCK,
610 * then the call to GSocket_Connect() has failed.
612 closesocket(sck
->m_fd
);
613 sck
->m_fd
= INVALID_SOCKET
;
614 sck
->m_error
= GSOCK_IOERR
;
618 return GSOCK_NOERROR
;
621 /* Datagram sockets */
623 /* GSocket_SetNonOriented:
624 * Sets up this socket as a non-connection oriented (datagram) socket.
625 * Before using this function, the local address must have been set
626 * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
627 * on success, or one of the following otherwise.
630 * GSOCK_INVSOCK - the socket is in use.
631 * GSOCK_INVADDR - the local address has not been set.
632 * GSOCK_IOERR - low-level error.
634 GSocketError
GSocket_SetNonOriented(GSocket
*sck
)
640 if (sck
->m_fd
!= INVALID_SOCKET
)
642 sck
->m_error
= GSOCK_INVSOCK
;
643 return GSOCK_INVSOCK
;
648 sck
->m_error
= GSOCK_INVADDR
;
649 return GSOCK_INVADDR
;
652 /* Initialize all fields */
653 sck
->m_stream
= FALSE
;
654 sck
->m_server
= FALSE
;
655 sck
->m_oriented
= FALSE
;
657 /* Create the socket */
658 sck
->m_fd
= socket(sck
->m_local
->m_realfamily
, SOCK_DGRAM
, 0);
660 if (sck
->m_fd
== INVALID_SOCKET
)
662 sck
->m_error
= GSOCK_IOERR
;
666 ioctlsocket(sck
->m_fd
, FIONBIO
, (u_long FAR
*) &arg
);
667 _GSocket_Enable_Events(sck
);
669 /* Bind to the local address,
670 * and retrieve the actual address bound.
672 if ((bind(sck
->m_fd
, sck
->m_local
->m_addr
, sck
->m_local
->m_len
) != 0) ||
673 (getsockname(sck
->m_fd
,
674 sck
->m_local
->m_addr
,
675 (SOCKLEN_T
*)&sck
->m_local
->m_len
) != 0))
677 closesocket(sck
->m_fd
);
678 sck
->m_fd
= INVALID_SOCKET
;
679 sck
->m_error
= GSOCK_IOERR
;
683 return GSOCK_NOERROR
;
689 /* Like recv(), send(), ... */
690 int GSocket_Read(GSocket
*socket
, char *buffer
, int size
)
694 assert(socket
!= NULL
);
696 /* Reenable INPUT events */
697 socket
->m_detected
&= ~GSOCK_INPUT_FLAG
;
699 if (socket
->m_fd
== INVALID_SOCKET
|| socket
->m_server
)
701 socket
->m_error
= GSOCK_INVSOCK
;
705 /* If the socket is blocking, wait for data (with a timeout) */
706 if (_GSocket_Input_Timeout(socket
) == GSOCK_TIMEDOUT
)
710 if (socket
->m_stream
)
711 ret
= _GSocket_Recv_Stream(socket
, buffer
, size
);
713 ret
= _GSocket_Recv_Dgram(socket
, buffer
, size
);
715 if (ret
== SOCKET_ERROR
)
717 if (WSAGetLastError() != WSAEWOULDBLOCK
)
718 socket
->m_error
= GSOCK_IOERR
;
720 socket
->m_error
= GSOCK_WOULDBLOCK
;
727 int GSocket_Write(GSocket
*socket
, const char *buffer
, int size
)
731 assert(socket
!= NULL
);
733 if (socket
->m_fd
== INVALID_SOCKET
|| socket
->m_server
)
735 socket
->m_error
= GSOCK_INVSOCK
;
739 /* If the socket is blocking, wait for writability (with a timeout) */
740 if (_GSocket_Output_Timeout(socket
) == GSOCK_TIMEDOUT
)
744 if (socket
->m_stream
)
745 ret
= _GSocket_Send_Stream(socket
, buffer
, size
);
747 ret
= _GSocket_Send_Dgram(socket
, buffer
, size
);
749 if (ret
== SOCKET_ERROR
)
751 if (WSAGetLastError() != WSAEWOULDBLOCK
)
752 socket
->m_error
= GSOCK_IOERR
;
754 socket
->m_error
= GSOCK_WOULDBLOCK
;
756 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
757 * does). Once the first OUTPUT event is received, users can assume
758 * that the socket is writable until a read operation fails. Only then
759 * will further OUTPUT events be posted.
761 socket
->m_detected
&= ~GSOCK_OUTPUT_FLAG
;
769 * Polls the socket to determine its status. This function will
770 * check for the events specified in the 'flags' parameter, and
771 * it will return a mask indicating which operations can be
772 * performed. This function won't block, regardless of the
773 * mode (blocking | nonblocking) of the socket.
775 GSocketEventFlags
GSocket_Select(GSocket
*socket
, GSocketEventFlags flags
)
777 assert(socket
!= NULL
);
779 return flags
& socket
->m_detected
;
784 /* GSocket_SetNonBlocking:
785 * Sets the socket to non-blocking mode. All IO calls will return
788 void GSocket_SetNonBlocking(GSocket
*socket
, bool non_block
)
790 assert(socket
!= NULL
);
792 socket
->m_non_blocking
= non_block
;
795 /* GSocket_SetTimeout:
796 * Sets the timeout for blocking calls. Time is expressed in
799 void GSocket_SetTimeout(GSocket
*socket
, unsigned long millis
)
801 assert(socket
!= NULL
);
803 socket
->m_timeout
.tv_sec
= (millis
/ 1000);
804 socket
->m_timeout
.tv_usec
= (millis
% 1000) * 1000;
808 * Returns the last error occured for this socket. Note that successful
809 * operations do not clear this back to GSOCK_NOERROR, so use it only
812 GSocketError
GSocket_GetError(GSocket
*socket
)
814 assert(socket
!= NULL
);
816 return socket
->m_error
;
823 * There is data to be read in the input buffer. If, after a read
824 * operation, there is still data available, the callback function will
827 * The socket is available for writing. That is, the next write call
828 * won't block. This event is generated only once, when the connection is
829 * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
830 * when the output buffer empties again. This means that the app should
831 * assume that it can write since the first OUTPUT event, and no more
832 * OUTPUT events will be generated unless an error occurs.
834 * Connection succesfully established, for client sockets, or incoming
835 * client connection, for server sockets. Wait for this event (also watch
836 * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
838 * The connection is lost (or a connection request failed); this could
839 * be due to a failure, or due to the peer closing it gracefully.
842 /* GSocket_SetCallback:
843 * Enables the callbacks specified by 'flags'. Note that 'flags'
844 * may be a combination of flags OR'ed toghether, so the same
845 * callback function can be made to accept different events.
846 * The callback function must have the following prototype:
848 * void function(GSocket *socket, GSocketEvent event, char *cdata)
850 void GSocket_SetCallback(GSocket
*socket
, GSocketEventFlags flags
,
851 GSocketCallback callback
, char *cdata
)
855 assert(socket
!= NULL
);
857 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
859 if ((flags
& (1 << count
)) != 0)
861 socket
->m_cbacks
[count
] = callback
;
862 socket
->m_data
[count
] = cdata
;
867 /* GSocket_UnsetCallback:
868 * Disables all callbacks specified by 'flags', which may be a
869 * combination of flags OR'ed toghether.
871 void GSocket_UnsetCallback(GSocket
*socket
, GSocketEventFlags flags
)
875 assert(socket
!= NULL
);
877 for (count
= 0; count
< GSOCK_MAX_EVENT
; count
++)
879 if ((flags
& (1 << count
)) != 0)
881 socket
->m_cbacks
[count
] = NULL
;
882 socket
->m_data
[count
] = NULL
;
890 /* _GSocket_Enable_Events:
891 * Enable all event notifications; we need to be notified of all
892 * events for internal processing, but we will only notify users
893 * when an appropiate callback function has been installed.
895 void _GSocket_Enable_Events(GSocket
*socket
)
897 assert (socket
!= NULL
);
899 if (socket
->m_fd
!= INVALID_SOCKET
)
901 WSAAsyncSelect(socket
->m_fd
, hWin
, socket
->m_msgnumber
,
902 FD_READ
| FD_WRITE
| FD_ACCEPT
| FD_CONNECT
| FD_CLOSE
);
906 /* _GSocket_Disable_Events:
907 * Disable event notifications (when shutdowning the socket)
909 void _GSocket_Disable_Events(GSocket
*socket
)
911 assert (socket
!= NULL
);
913 if (socket
->m_fd
!= INVALID_SOCKET
)
915 WSAAsyncSelect(socket
->m_fd
, hWin
, socket
->m_msgnumber
, 0);
920 LRESULT CALLBACK
_GSocket_Internal_WinProc(HWND hWnd
,
927 GSocketCallback cback
;
930 if (uMsg
>= WM_USER
&& uMsg
<= (WM_USER
+ MAXSOCKETS
- 1))
932 EnterCriticalSection(&critical
);
933 socket
= socketList
[(uMsg
- WM_USER
)];
938 /* Check that the socket still exists (it has not been
939 * destroyed) and for safety, check that the m_fd field
940 * is what we expect it to be.
942 if ((socket
!= NULL
) && (socket
->m_fd
== wParam
))
944 switch WSAGETSELECTEVENT(lParam
)
946 case FD_READ
: event
= GSOCK_INPUT
; break;
947 case FD_WRITE
: event
= GSOCK_OUTPUT
; break;
948 case FD_ACCEPT
: event
= GSOCK_CONNECTION
; break;
951 if (WSAGETSELECTERROR(lParam
) != 0)
954 event
= GSOCK_CONNECTION
;
957 case FD_CLOSE
: event
= GSOCK_LOST
; break;
962 cback
= socket
->m_cbacks
[event
];
963 data
= socket
->m_data
[event
];
965 if (event
== GSOCK_LOST
)
966 socket
->m_detected
= GSOCK_LOST_FLAG
;
968 socket
->m_detected
|= (1 << event
);
972 /* OK, we can now leave the critical section because we have
973 * already obtained the callback address (we make no further
974 * accesses to socket->whatever). However, the app should
975 * be prepared to handle events from a socket that has just
978 LeaveCriticalSection(&critical
);
981 (cback
)(socket
, event
, data
);
986 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
990 /* _GSocket_Input_Timeout:
991 * For blocking sockets, wait until data is available or
992 * until timeout ellapses.
994 GSocketError
_GSocket_Input_Timeout(GSocket
*socket
)
998 if (!socket
->m_non_blocking
)
1001 FD_SET(socket
->m_fd
, &readfds
);
1002 if (select(0, &readfds
, NULL
, NULL
, &socket
->m_timeout
) == 0)
1004 socket
->m_error
= GSOCK_TIMEDOUT
;
1005 return GSOCK_TIMEDOUT
;
1008 return GSOCK_NOERROR
;
1011 /* _GSocket_Output_Timeout:
1012 * For blocking sockets, wait until data can be sent without
1013 * blocking or until timeout ellapses.
1015 GSocketError
_GSocket_Output_Timeout(GSocket
*socket
)
1019 if (!socket
->m_non_blocking
)
1022 FD_SET(socket
->m_fd
, &writefds
);
1023 if (select(0, NULL
, &writefds
, NULL
, &socket
->m_timeout
) == 0)
1025 socket
->m_error
= GSOCK_TIMEDOUT
;
1026 return GSOCK_TIMEDOUT
;
1029 return GSOCK_NOERROR
;
1032 /* _GSocket_Connect_Timeout:
1033 * For blocking sockets, wait until the connection is
1034 * established or fails, or until timeout ellapses.
1036 GSocketError
_GSocket_Connect_Timeout(GSocket
*socket
)
1042 FD_ZERO(&exceptfds
);
1043 FD_SET(socket
->m_fd
, &writefds
);
1044 FD_SET(socket
->m_fd
, &exceptfds
);
1045 if (select(0, NULL
, &writefds
, &exceptfds
, &socket
->m_timeout
) == 0)
1047 socket
->m_error
= GSOCK_TIMEDOUT
;
1048 return GSOCK_TIMEDOUT
;
1050 if (!FD_ISSET(socket
->m_fd
, &writefds
))
1052 socket
->m_error
= GSOCK_IOERR
;
1056 return GSOCK_NOERROR
;
1059 int _GSocket_Recv_Stream(GSocket
*socket
, char *buffer
, int size
)
1061 return recv(socket
->m_fd
, buffer
, size
, 0);
1064 int _GSocket_Recv_Dgram(GSocket
*socket
, char *buffer
, int size
)
1066 struct sockaddr from
;
1067 SOCKLEN_T fromlen
= sizeof(from
);
1071 ret
= recvfrom(socket
->m_fd
, buffer
, size
, 0, &from
, &fromlen
);
1073 if (ret
== SOCKET_ERROR
)
1074 return SOCKET_ERROR
;
1076 /* Translate a system address into a GSocket address */
1077 if (!socket
->m_peer
)
1079 socket
->m_peer
= GAddress_new();
1080 if (!socket
->m_peer
)
1082 socket
->m_error
= GSOCK_MEMERR
;
1086 err
= _GAddress_translate_from(socket
->m_peer
, &from
, fromlen
);
1087 if (err
!= GSOCK_NOERROR
)
1089 GAddress_destroy(socket
->m_peer
);
1090 socket
->m_peer
= NULL
;
1091 socket
->m_error
= err
;
1098 int _GSocket_Send_Stream(GSocket
*socket
, const char *buffer
, int size
)
1100 return send(socket
->m_fd
, buffer
, size
, 0);
1103 int _GSocket_Send_Dgram(GSocket
*socket
, const char *buffer
, int size
)
1105 struct sockaddr
*addr
;
1109 if (!socket
->m_peer
)
1111 socket
->m_error
= GSOCK_INVADDR
;
1115 err
= _GAddress_translate_to(socket
->m_peer
, &addr
, &len
);
1116 if (err
!= GSOCK_NOERROR
)
1118 socket
->m_error
= err
;
1122 ret
= sendto(socket
->m_fd
, buffer
, size
, 0, addr
, len
);
1124 /* Frees memory allocated by _GAddress_translate_to */
1132 * -------------------------------------------------------------------------
1134 * -------------------------------------------------------------------------
1137 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY
1138 * or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address
1139 * to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
1141 #define CHECK_ADDRESS(address, family, retval) \
1143 if (address->m_family == GSOCK_NOFAMILY) \
1144 if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
1145 return address->m_error; \
1146 if (address->m_family != GSOCK_##family) \
1148 address->m_error = GSOCK_INVADDR; \
1153 GAddress
*GAddress_new()
1157 if ((address
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1160 address
->m_family
= GSOCK_NOFAMILY
;
1161 address
->m_addr
= NULL
;
1167 GAddress
*GAddress_copy(GAddress
*address
)
1171 assert(address
!= NULL
);
1173 if ((addr2
= (GAddress
*) malloc(sizeof(GAddress
))) == NULL
)
1176 memcpy(addr2
, address
, sizeof(GAddress
));
1178 if (address
->m_addr
)
1180 addr2
->m_addr
= (struct sockaddr
*) malloc(addr2
->m_len
);
1181 if (addr2
->m_addr
== NULL
)
1186 memcpy(addr2
->m_addr
, address
->m_addr
, addr2
->m_len
);
1192 void GAddress_destroy(GAddress
*address
)
1194 assert(address
!= NULL
);
1199 void GAddress_SetFamily(GAddress
*address
, GAddressType type
)
1201 assert(address
!= NULL
);
1203 address
->m_family
= type
;
1206 GAddressType
GAddress_GetFamily(GAddress
*address
)
1208 assert(address
!= NULL
);
1210 return address
->m_family
;
1213 GSocketError
_GAddress_translate_from(GAddress
*address
,
1214 struct sockaddr
*addr
, int len
)
1216 address
->m_realfamily
= addr
->sa_family
;
1217 switch (addr
->sa_family
)
1220 address
->m_family
= GSOCK_INET
;
1223 address
->m_family
= GSOCK_UNIX
;
1227 address
->m_family
= GSOCK_INET6
;
1232 address
->m_error
= GSOCK_INVOP
;
1237 if (address
->m_addr
)
1238 free(address
->m_addr
);
1240 address
->m_len
= len
;
1241 address
->m_addr
= (struct sockaddr
*) malloc(len
);
1243 if (address
->m_addr
== NULL
)
1245 address
->m_error
= GSOCK_MEMERR
;
1246 return GSOCK_MEMERR
;
1248 memcpy(address
->m_addr
, addr
, len
);
1250 return GSOCK_NOERROR
;
1253 GSocketError
_GAddress_translate_to(GAddress
*address
,
1254 struct sockaddr
**addr
, int *len
)
1256 if (!address
->m_addr
)
1258 address
->m_error
= GSOCK_INVADDR
;
1259 return GSOCK_INVADDR
;
1262 *len
= address
->m_len
;
1263 *addr
= (struct sockaddr
*) malloc(address
->m_len
);
1266 address
->m_error
= GSOCK_MEMERR
;
1267 return GSOCK_MEMERR
;
1270 memcpy(*addr
, address
->m_addr
, address
->m_len
);
1271 return GSOCK_NOERROR
;
1275 * -------------------------------------------------------------------------
1276 * Internet address family
1277 * -------------------------------------------------------------------------
1280 GSocketError
_GAddress_Init_INET(GAddress
*address
)
1282 address
->m_len
= sizeof(struct sockaddr_in
);
1283 address
->m_addr
= (struct sockaddr
*) malloc(address
->m_len
);
1284 if (address
->m_addr
== NULL
)
1286 address
->m_error
= GSOCK_MEMERR
;
1287 return GSOCK_MEMERR
;
1290 address
->m_family
= GSOCK_INET
;
1291 address
->m_realfamily
= PF_INET
;
1292 ((struct sockaddr_in
*)address
->m_addr
)->sin_family
= AF_INET
;
1293 ((struct sockaddr_in
*)address
->m_addr
)->sin_addr
.s_addr
= INADDR_ANY
;
1295 return GSOCK_NOERROR
;
1298 GSocketError
GAddress_INET_SetHostName(GAddress
*address
, const char *hostname
)
1301 struct in_addr
*addr
;
1303 assert(address
!= NULL
);
1305 CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
);
1307 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1309 addr
->s_addr
= inet_addr(hostname
);
1311 /* If it is a numeric host name, convert it now */
1312 if (addr
->s_addr
== INADDR_NONE
)
1314 struct in_addr
*array_addr
;
1316 /* It is a real name, we solve it */
1317 if ((he
= gethostbyname(hostname
)) == NULL
)
1319 /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
1320 address
->m_error
= GSOCK_NOHOST
;
1321 return GSOCK_NOHOST
;
1323 array_addr
= (struct in_addr
*) *(he
->h_addr_list
);
1324 addr
->s_addr
= array_addr
[0].s_addr
;
1326 return GSOCK_NOERROR
;
1329 GSocketError
GAddress_INET_SetAnyAddress(GAddress
*address
)
1331 return GAddress_INET_SetHostAddress(address
, INADDR_ANY
);
1334 GSocketError
GAddress_INET_SetHostAddress(GAddress
*address
,
1335 unsigned long hostaddr
)
1337 struct in_addr
*addr
;
1339 assert(address
!= NULL
);
1341 CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
);
1343 addr
= &(((struct sockaddr_in
*)address
->m_addr
)->sin_addr
);
1344 addr
->s_addr
= hostaddr
;
1346 return GSOCK_NOERROR
;
1349 GSocketError
GAddress_INET_SetPortName(GAddress
*address
, const char *port
,
1350 const char *protocol
)
1353 struct sockaddr_in
*addr
;
1355 assert(address
!= NULL
);
1356 CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
);
1360 address
->m_error
= GSOCK_INVPORT
;
1361 return GSOCK_INVPORT
;
1364 se
= getservbyname(port
, protocol
);
1367 if (isdigit(port
[0]))
1371 port_int
= atoi(port
);
1372 addr
= (struct sockaddr_in
*)address
->m_addr
;
1373 addr
->sin_port
= htons((u_short
) port_int
);
1374 return GSOCK_NOERROR
;
1377 address
->m_error
= GSOCK_INVPORT
;
1378 return GSOCK_INVPORT
;
1381 addr
= (struct sockaddr_in
*)address
->m_addr
;
1382 addr
->sin_port
= se
->s_port
;
1384 return GSOCK_NOERROR
;
1387 GSocketError
GAddress_INET_SetPort(GAddress
*address
, unsigned short port
)
1389 struct sockaddr_in
*addr
;
1391 assert(address
!= NULL
);
1392 CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
);
1394 addr
= (struct sockaddr_in
*)address
->m_addr
;
1395 addr
->sin_port
= htons(port
);
1397 return GSOCK_NOERROR
;
1400 GSocketError
GAddress_INET_GetHostName(GAddress
*address
, char *hostname
, size_t sbuf
)
1404 struct sockaddr_in
*addr
;
1406 assert(address
!= NULL
);
1407 CHECK_ADDRESS(address
, INET
, GSOCK_INVADDR
);
1409 addr
= (struct sockaddr_in
*)address
->m_addr
;
1410 addr_buf
= (char *)&(addr
->sin_addr
);
1412 he
= gethostbyaddr(addr_buf
, sizeof(addr
->sin_addr
), AF_INET
);
1415 address
->m_error
= GSOCK_NOHOST
;
1416 return GSOCK_NOHOST
;
1419 strncpy(hostname
, he
->h_name
, sbuf
);
1421 return GSOCK_NOERROR
;
1424 unsigned long GAddress_INET_GetHostAddress(GAddress
*address
)
1426 struct sockaddr_in
*addr
;
1428 assert(address
!= NULL
);
1429 CHECK_ADDRESS(address
, INET
, 0);
1431 addr
= (struct sockaddr_in
*)address
->m_addr
;
1433 return addr
->sin_addr
.s_addr
;
1436 unsigned short GAddress_INET_GetPort(GAddress
*address
)
1438 struct sockaddr_in
*addr
;
1440 assert(address
!= NULL
);
1441 CHECK_ADDRESS(address
, INET
, 0);
1443 addr
= (struct sockaddr_in
*)address
->m_addr
;
1444 return ntohs(addr
->sin_port
);
1448 * -------------------------------------------------------------------------
1449 * Unix address family
1450 * -------------------------------------------------------------------------
1454 #pragma warning(disable:4100) /* unreferenced formal parameter */
1455 #endif /* Visual C++ */
1457 GSocketError
_GAddress_Init_UNIX(GAddress
*address
)
1459 assert (address
!= NULL
);
1460 address
->m_error
= GSOCK_INVADDR
;
1461 return GSOCK_INVADDR
;
1464 GSocketError
GAddress_UNIX_SetPath(GAddress
*address
, const char *path
)
1466 assert (address
!= NULL
);
1467 address
->m_error
= GSOCK_INVADDR
;
1468 return GSOCK_INVADDR
;
1471 GSocketError
GAddress_UNIX_GetPath(GAddress
*address
, char *path
, size_t sbuf
)
1473 assert (address
!= NULL
);
1474 address
->m_error
= GSOCK_INVADDR
;
1475 return GSOCK_INVADDR
;
1478 #else /* !wxUSE_SOCKETS */
1481 * Translation unit shouldn't be empty, so include this typedef to make the
1482 * compiler (VC++ 6.0, for example) happy
1484 typedef (*wxDummy
)();
1486 #endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */