replaced my recent GSocket_SetReuseAddr() addition with GSocket_SetReusable() from the patch 992473; it also adds and documents wxSOCKET_REUSEADDR flag
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@28494 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -593,6 +593,7 @@ The following flags can be used:
|
||||
\twocolitem{{\bf wxSOCKET\_NOWAIT}}{Read/write as much data as possible and return immediately.}
|
||||
\twocolitem{{\bf wxSOCKET\_WAITALL}}{Wait for all required data to be read/written unless an error occurs.}
|
||||
\twocolitem{{\bf wxSOCKET\_BLOCK}}{Block the GUI (do not yield) while reading/writing data.}
|
||||
\twocolitem{{\bf wxSOCKET\_REUSEADDR}}{Allows the use of an in-use port (wxServerSocket only)}
|
||||
\end{twocollist}
|
||||
|
||||
A brief overview on how to use these flags follows.
|
||||
@@ -626,6 +627,13 @@ during IO calls, so the GUI will remain blocked until the operation
|
||||
completes. If it is not used, then the application must take extra
|
||||
care to avoid unwanted reentrance.
|
||||
|
||||
The {\bf wxSOCKET\_REUSEADDR} flag controls the use of the SO_REUSEADDR standard
|
||||
setsockopt() flag. This flag allows the socket to bind to a port that is already in use.
|
||||
This is mostly used on UNIX-based systems to allow rapid starting and stopping of a server -
|
||||
otherwise you may have to wait several minutes for the port to become available.
|
||||
This option can have suprising platform dependent behavior, check the documentation for
|
||||
your platforms implementation of setsockopt().
|
||||
|
||||
So:
|
||||
|
||||
{\bf wxSOCKET\_NONE} will try to read at least SOME data, no matter how much.
|
||||
@@ -639,6 +647,8 @@ the data.
|
||||
{\bf wxSOCKET\_BLOCK} has nothing to do with the previous flags and
|
||||
it controls whether the GUI blocks.
|
||||
|
||||
(\bf wxSOCKET\_REUSEADDR} controls special platform-specific behavior for wxServerSocket.
|
||||
|
||||
%
|
||||
% SetNotify
|
||||
%
|
||||
|
@@ -235,6 +235,15 @@ GSocket *GSocket_WaitConnection(GSocket *socket);
|
||||
*/
|
||||
GSocketError GSocket_Connect(GSocket *socket, GSocketStream stream);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Datagram sockets */
|
||||
|
||||
@@ -277,7 +286,6 @@ GSocketError GSocket_GetSockOpt(GSocket *socket, int level, int optname,
|
||||
|
||||
GSocketError GSocket_SetSockOpt(GSocket *socket, int level, int optname,
|
||||
const void *optval, int optlen);
|
||||
GSocketError GSocket_SetReuseAddr(GSocket *socket);
|
||||
|
||||
void GSocket_Streamed(GSocket *socket);
|
||||
void GSocket_Unstreamed(GSocket *socket);
|
||||
|
@@ -50,6 +50,7 @@ struct _GSocket
|
||||
int m_stream;
|
||||
int m_oriented;
|
||||
int m_establishing;
|
||||
int m_reusable;
|
||||
struct timeval m_timeout;
|
||||
|
||||
/* Callbacks */
|
||||
|
@@ -74,7 +74,8 @@ enum
|
||||
wxSOCKET_NONE = 0,
|
||||
wxSOCKET_NOWAIT = 1,
|
||||
wxSOCKET_WAITALL = 2,
|
||||
wxSOCKET_BLOCK = 4
|
||||
wxSOCKET_BLOCK = 4,
|
||||
wxSOCKET_REUSEADDR = 8
|
||||
};
|
||||
|
||||
enum wxSocketType
|
||||
|
@@ -1068,6 +1068,11 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
|
||||
// Setup the socket as server
|
||||
|
||||
GSocket_SetLocal(m_socket, addr_man.GetAddress());
|
||||
|
||||
if (GetFlags() & wxSOCKET_REUSEADDR) {
|
||||
GSocket_SetReusable(m_socket);
|
||||
}
|
||||
|
||||
if (GSocket_SetServer(m_socket) != GSOCK_NOERROR)
|
||||
{
|
||||
GSocket_destroy(m_socket);
|
||||
|
@@ -483,6 +483,12 @@ GSocketError GSocket_SetServer(GSocket *sck)
|
||||
#endif
|
||||
_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(socket->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.
|
||||
@@ -594,6 +600,16 @@ GSocket *GSocket_WaitConnection(GSocket *socket)
|
||||
return connection;
|
||||
}
|
||||
|
||||
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:
|
||||
@@ -1144,15 +1160,6 @@ GSocketError GSocket_SetSockOpt(GSocket *socket, int level, int optname,
|
||||
return GSOCK_OPTERR;
|
||||
}
|
||||
|
||||
GSocketError GSocket_SetReuseAddr(GSocket *socket)
|
||||
{
|
||||
/* allow a socket to re-bind if the socket is in the TIME_WAIT
|
||||
state after being previously closed.
|
||||
*/
|
||||
u_long arg = 1;
|
||||
setsockopt(socket->m_fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&arg, sizeof(u_long));
|
||||
}
|
||||
|
||||
void GSocket_Streamed(GSocket *socket)
|
||||
{
|
||||
socket->m_stream = TRUE;
|
||||
|
Reference in New Issue
Block a user