2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
|
*/
Tcl_Channel
Tcl_OpenTcpServerEx(
Tcl_Interp *interp, /* For error reporting - may be NULL. */
int port, /* Port number to open. */
const char *myHost, /* Name of local host. */
unsigned int flags, /* Flags (not used) */
Tcl_TcpAcceptProc *acceptProc,
/* Callback for accepting connections from new
* clients. */
ClientData acceptProcData) /* Data for the callback. */
{
SOCKET sock = INVALID_SOCKET;
unsigned short chosenport = 0;
struct addrinfo *addrlist = NULL;
struct addrinfo *addrPtr; /* Socket address to listen on. */
TcpState *statePtr = NULL; /* The returned value. */
char channelName[SOCK_CHAN_LENGTH];
u_long flag = 1; /* Indicates nonblocking mode. */
const char *errorMsg = NULL;
if (TclpHasSockets(interp) != TCL_OK) {
return NULL;
}
/*
* Check that WinSock is initialized; do not call it if not, to prevent
|
|
>
|
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
|
*/
Tcl_Channel
Tcl_OpenTcpServerEx(
Tcl_Interp *interp, /* For error reporting - may be NULL. */
int port, /* Port number to open. */
const char *myHost, /* Name of local host. */
unsigned int flags, /* Flags. */
Tcl_TcpAcceptProc *acceptProc,
/* Callback for accepting connections from new
* clients. */
ClientData acceptProcData) /* Data for the callback. */
{
SOCKET sock = INVALID_SOCKET;
unsigned short chosenport = 0;
struct addrinfo *addrlist = NULL;
struct addrinfo *addrPtr; /* Socket address to listen on. */
TcpState *statePtr = NULL; /* The returned value. */
char channelName[SOCK_CHAN_LENGTH];
u_long flag = 1; /* Indicates nonblocking mode. */
const char *errorMsg = NULL;
int optvalue;
if (TclpHasSockets(interp) != TCL_OK) {
return NULL;
}
/*
* Check that WinSock is initialized; do not call it if not, to prevent
|
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
|
if (port == 0 && chosenport != 0) {
((struct sockaddr_in *) addrPtr->ai_addr)->sin_port =
htons(chosenport);
}
/*
* Bind to the specified port. Note that we must not call
* setsockopt with SO_REUSEADDR or SO_REUSEPORT because Microsoft
* allows addresses and ports to be reused even if they are still in use.
*
* Bind should not be affected by the socket having already been
* set into nonblocking mode. If there is trouble, this is one
* place to look for bugs.
*/
if (bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen)
|
>
>
>
>
>
>
>
>
>
>
|
<
<
|
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
|
if (port == 0 && chosenport != 0) {
((struct sockaddr_in *) addrPtr->ai_addr)->sin_port =
htons(chosenport);
}
/*
* The SO_REUSEADDR option on Windows behaves like SO_REUSEPORT on unix
* systems.
*/
if (flags & TCL_TCPSERVER_REUSEPORT) {
optvalue = 1;
(void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
(char *) &optvalue, sizeof(optvalue));
}
/*
* Bind to the specified port.
*
* Bind should not be affected by the socket having already been
* set into nonblocking mode. If there is trouble, this is one
* place to look for bugs.
*/
if (bind(sock, addrPtr->ai_addr, addrPtr->ai_addrlen)
|