* Name: gsocket.c
* Author: Guillermo Rodriguez Garcia <guille@iies.es>
* Purpose: GSocket main MSW file
- * Licence: The wxWindows licence
+ * Licence: The wxWidgets licence
* CVSID: $Id$
* -------------------------------------------------------------------------
*/
* warning: unreferenced formal parameter.
*/
# pragma warning(disable:4100)
+
+#ifdef __WXWINCE__
+ /* windows.h results in tons of warnings at max warning level */
+# ifdef _MSC_VER
+# pragma warning(push, 1)
+# endif
+# include <windows.h>
+# ifdef _MSC_VER
+# pragma warning(pop)
+# pragma warning(disable:4514)
+# endif
+#endif
+
#endif /* _MSC_VER */
#include <winsock.h>
#ifndef __GSOCKET_STANDALONE__
-# include "wx/defs.h"
-# include "wx/setup.h"
+# include "wx/platform.h"
+# include "wx/setup.h"
#endif
#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
{
gs_gui_functions = guifunc;
}
-
+
int GSocket_Init(void)
{
WSADATA wsaData;
-
+
if (gs_gui_functions)
{
if ( !gs_gui_functions->GUI_Init() )
{
gs_gui_functions->GUI_Cleanup();
}
-
+
/* Cleanup WinSocket */
WSACleanup();
}
socket->m_timeout.tv_sec = 10 * 60; /* 10 minutes */
socket->m_timeout.tv_usec = 0;
socket->m_establishing = FALSE;
+ socket->m_reusable = FALSE;
/* Per-socket GUI-specific initialization */
success = _GSocket_GUI_Init_Socket(socket);
/* Initialize all fields */
sck->m_server = TRUE;
sck->m_stream = TRUE;
- sck->m_oriented = TRUE;
/* Create the socket */
sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
ioctlsocket(sck->m_fd, FIONBIO, (u_long FAR *) &arg);
_GSocket_Enable_Events(sck);
+ /* allow a socket to re-bind if the socket is in the TIME_WAIT
+ state after being previously closed.
+ */
+ if (sck->m_reusable) {
+ setsockopt(sck->m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(u_long));
+ }
+
/* Bind to the local address,
* retrieve the actual address bound,
* and listen up to 5 connections.
/* Initialize all fields */
connection->m_server = FALSE;
connection->m_stream = TRUE;
- connection->m_oriented = TRUE;
/* Setup the peer address field */
connection->m_peer = GAddress_new();
return connection;
}
+/* GSocket_SetReusable:
+* Simply sets the m_resuable flag on the socket. GSocket_SetServer will
+* make the appropriate setsockopt() call.
+* Implemented as a GSocket function because clients (ie, wxSocketServer)
+* don't have access to the GSocket struct information.
+* Returns TRUE if the flag was set correctly, FALSE if an error occured
+* (ie, if the parameter was NULL)
+*/
+int GSocket_SetReusable(GSocket *socket)
+{
+ /* socket must not be null, and must not be in use/already bound */
+ if (NULL != socket && socket->m_fd == INVALID_SOCKET) {
+ socket->m_reusable = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
/* Client specific parts */
/* GSocket_Connect:
/* Streamed or dgram socket? */
sck->m_stream = (stream == GSOCK_STREAMED);
- sck->m_oriented = TRUE;
sck->m_server = FALSE;
sck->m_establishing = FALSE;
/* Initialize all fields */
sck->m_stream = FALSE;
sck->m_server = FALSE;
- sck->m_oriented = FALSE;
/* Create the socket */
sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
fd_set readfds;
fd_set writefds;
fd_set exceptfds;
- static const struct timeval tv = { 0, 0 };
assert(socket != NULL);
FD_ZERO(&writefds);
FD_ZERO(&exceptfds);
FD_SET(socket->m_fd, &readfds);
- FD_SET(socket->m_fd, &writefds);
+ if (flags & GSOCK_OUTPUT_FLAG || flags & GSOCK_CONNECTION_FLAG)
+ FD_SET(socket->m_fd, &writefds);
FD_SET(socket->m_fd, &exceptfds);
/* Check 'sticky' CONNECTION flag first */
}
/* Try select now */
- if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds, &tv) <= 0)
+ if (select(socket->m_fd + 1, &readfds, &writefds, &exceptfds,
+ &socket->m_timeout) <= 0)
{
/* What to do here? */
return (result & flags);
{
char c;
- if (recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
+ if (!socket->m_stream || recv(socket->m_fd, &c, 1, MSG_PEEK) > 0)
{
result |= GSOCK_INPUT_FLAG;
}
{
socket->m_detected = GSOCK_LOST_FLAG;
socket->m_establishing = FALSE;
-
+
/* LOST event: Abort any further processing */
return (GSOCK_LOST_FLAG & flags);
}
}
}
+GSocketError GSocket_GetSockOpt(GSocket *socket, int level, int optname,
+ void *optval, int *optlen)
+{
+ if (getsockopt(socket->m_fd, level, optname, optval, optlen) == 0)
+ {
+ return GSOCK_NOERROR;
+ }
+ return GSOCK_OPTERR;
+}
+
+GSocketError GSocket_SetSockOpt(GSocket *socket, int level, int optname,
+ const void *optval, int optlen)
+{
+ if (setsockopt(socket->m_fd, level, optname, optval, optlen) == 0)
+ {
+ return GSOCK_NOERROR;
+ }
+ return GSOCK_OPTERR;
+}
+
/* Internals (IO) */
/* _GSocket_Input_Timeout:
}
address->m_family = GSOCK_INET;
- address->m_realfamily = PF_INET;
+ address->m_realfamily = AF_INET;
((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
CHECK_ADDRESS(address, INET);
addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
- addr->s_addr = hostaddr;
+ addr->s_addr = htonl(hostaddr);;
return GSOCK_NOERROR;
}
addr = (struct sockaddr_in *)address->m_addr;
- return addr->sin_addr.s_addr;
+ return ntohl(addr->sin_addr.s_addr);
}
unsigned short GAddress_INET_GetPort(GAddress *address)
GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
{
+#if defined(__BORLANDC__)
+ /* prevents unused variable message in Borland */
+ (void)path;
+#endif
assert (address != NULL);
address->m_error = GSOCK_INVADDR;
return GSOCK_INVADDR;
GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
{
+#if defined(__BORLANDC__)
+ /* prevents unused variable message in Borland */
+ (void)path;
+ (void)sbuf;
+#endif
assert (address != NULL);
address->m_error = GSOCK_INVADDR;
return GSOCK_INVADDR;