📄 sflsock.c
字号:
if (handle == INVALID_SOCKET) /* Unable to open a socket */
{
ip_nonblock = old_nonblock;
return (INVALID_SOCKET);
}
rc = connect ((SOCKET) handle, (struct sockaddr *) &sin, sizeof (sin));
if (rc == 0)
break; /* Connected okay */
else
{
# if (defined (__WINDOWS__))
if (WSAGetLastError () == WSAEWOULDBLOCK)
# else
if (errno == EINPROGRESS)
# endif
break; /* Still connecting, but okay */
}
/* Retry if we have any attempts left */
close_socket (handle);
if (--retries_left == 0) /* Connection failed */
{
connect_error_value = IP_CONNECTERROR;
ip_nonblock = old_nonblock;
return (INVALID_SOCKET);
}
sleep (retry_delay);
}
ip_nonblock = old_nonblock;
prepare_socket (handle); /* Set final blocking mode */
return (handle);
#elif (defined (FAKE_SOCKETS))
return (1); /* Return dummy handle */
#else
connect_error_value = IP_NOSOCKETS;
return (INVALID_SOCKET); /* Sockets not supported */
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: connect_to_peer
Synopsis:
Connects an unconnected TCP or UDP socket to a peer specified by a
sockaddr structure. Returns 0 if the connection succeeded, or
SOCKET_ERROR if there was a problem. In the latter case you can
get the reason for the error by calling sockmsg().
---------------------------------------------------------------------[>]-*/
int
connect_to_peer (
sock_t handle, /* Socket to connect */
const struct sockaddr_in *sin /* Socket address structure */
)
{
#if (defined (DOES_SOCKETS))
int
rc; /* Return code from call */
Bool
old_nonblock; /* Create non-blocking sockets */
ASSERT (sin);
old_nonblock = ip_nonblock;
# if (defined (BLOCKING_CONNECT))
ip_nonblock = FALSE; /* Block on this socket */
# endif
rc = connect ((SOCKET) handle, (struct sockaddr *) sin, sizeof (*sin));
ip_nonblock = old_nonblock;
prepare_socket (handle); /* Set final blocking mode */
# if (defined (__WINDOWS__))
return (win_error (rc));
# else
return (rc);
# endif
#else
connect_error_value = IP_NOSOCKETS;
return ((int) SOCKET_ERROR); /* Sockets not supported */
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: address_end_point
Synopsis:
Formats an address block (struct sockaddr_in) for the specified host
and service (port) information. Returns 0 if okay, SOCKET_ERROR if
there was an error, in which case you can call connect_error () to get
the reason for the error. This may be one of:
<TABLE>
IP_NOSOCKETS Sockets not supported on this system
IP_BADHOST Host is not known
</TABLE>
---------------------------------------------------------------------[>]-*/
int
address_end_point (
const char *host, /* Name of host, "" = localhost */
const char *service, /* Service name or port as string */
const char *protocol, /* Protocol "tcp" or "udp" */
struct sockaddr_in *sin /* Block for formatted address */
)
{
#if (defined (DOES_SOCKETS))
struct hostent
*phe; /* Host information entry */
struct servent
*pse; /* Service information entry */
char
hostname [MAXHOSTNAMELEN + 1]; /* Name of this system */
int
feedback = 0; /* Assume everything works */
ASSERT (service && *service);
ASSERT (protocol && *protocol);
ASSERT (sin);
connect_error_value = IP_NOERROR; /* Assume no errors */
memset ((void *) sin, 0, sizeof (*sin));
sin-> sin_family = AF_INET;
/* Map service name to a port number */
pse = getservbyname (service, protocol);
if (pse)
sin-> sin_port = htons ((short) (ntohs (pse-> s_port)));
else
sin-> sin_port = htons ((short) (atoi (service)));
/* Map host name to IP address, allowing for dotted decimal */
if (host && strused (host))
strcpy (hostname, host);
else
strcpy (hostname, "127.0.0.1");
/* Check if it's a valid IP address first */
sin-> sin_addr.s_addr = inet_addr (hostname);
if (sin-> sin_addr.s_addr == INADDR_NONE)
{
/* Not a dotted address -- try to translate the name */
phe = gethostbyname (hostname);
if (phe)
memcpy ((void *) &sin-> sin_addr, phe-> h_addr, phe-> h_length);
else
{ /* Cannot map to host */
connect_error_value = IP_BADHOST;
feedback = (int) SOCKET_ERROR;
}
}
return (feedback);
#else
connect_error_value = IP_NOSOCKETS;
return ((int) SOCKET_ERROR); /* Sockets not supported */
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: build_sockaddr
Synopsis:
Builds a socket address structure from the specified host and port
addresses. Does not return any value except the built structure.
---------------------------------------------------------------------[>]-*/
void
build_sockaddr (
struct sockaddr_in *sin, /* Socket address structure */
qbyte host, /* 32-bit host address */
dbyte port /* 16-bit port number */
)
{
ASSERT (sin);
sin-> sin_family = AF_INET;
sin-> sin_addr.s_addr = htonl (host);
sin-> sin_port = htons (port);
}
/* ---------------------------------------------------------------------[<]-
Function: socket_localaddr
Synopsis: Returns a string containing the local host address for the
specified connected socket. The string is formatted as a string
"n.n.n.n". Returns the address of a static string or a buffer that
is overwritten by each call. If sockets are not supported, or there
was an error, returns the loopback address "127.0.0.1".
---------------------------------------------------------------------[>]-*/
char *
socket_localaddr (
sock_t handle)
{
#define NTOA_MAX 16
#if (defined (DOES_SOCKETS))
static char
localaddr [NTOA_MAX + 1]; /* xxx.xxx.xxx.xxx */
struct sockaddr_in
sin; /* Address of local system */
if (get_sock_addr (handle, &sin, NULL, 0))
return ("127.0.0.1");
else
{
strncpy (localaddr, inet_ntoa (sin.sin_addr), NTOA_MAX);
return (localaddr);
}
#else
return ("127.0.0.1");
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: socket_peeraddr
Synopsis: Returns a string containing the peer host address for the
specified connected socket. The string is formatted as a string
"n.n.n.n". Returns the address of a static string or a buffer that
is overwritten by each call. If sockets are not supported, or there
was an error, returns the loopback address "127.0.0.1".
---------------------------------------------------------------------[>]-*/
char *
socket_peeraddr (
sock_t handle)
{
#if (defined (DOES_SOCKETS))
static char
peeraddr [NTOA_MAX + 1]; /* xxx.xxx.xxx.xxx */
struct sockaddr_in
sin; /* Address of peer system */
if (get_peer_addr (handle, &sin, NULL, 0))
return ("127.0.0.1");
else
{
strncpy (peeraddr, inet_ntoa (sin.sin_addr), NTOA_MAX);
return (peeraddr);
}
#else
return ("127.0.0.1");
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: socket_nodelay
Synopsis: Disables Nagle's algorithm for the specified socket; use this
when you want to ensure that data is sent outwards as fast as possible,
and when you are certain that Nagle's algorithm is causing a slowdown in
performance. Recommended for HTTP, but not recommended for telnet.
Returns 0 if okay, SOCKET_ERROR if there was a problem.
---------------------------------------------------------------------[>]-*/
int
socket_nodelay (
sock_t handle)
{
#if (defined (__WINDOWS__))
int
true_value = 1; /* Boolean value for setsockopt() */
return (setsockopt ((SOCKET) handle, IPPROTO_TCP, TCP_NODELAY,
(char *) &true_value, sizeof (true_value)));
#elif (defined (TCP_NODELAY) && defined (SOL_TCP))
int
true_value = 1; /* Boolean value for setsockopt() */
return (setsockopt ((SOCKET) handle, SOL_TCP, TCP_NODELAY,
(char *) &true_value, sizeof (true_value)));
#else
return (0); /* Not applicable to this system */
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: socket_is_alive
Synopsis:
Returns TRUE if the socket is open. Returns FALSE if the socket is no
longer accessible. You can use this function to check that a socket has
not been closed by the other party, before doing reading or writing.
---------------------------------------------------------------------[>]-*/
Bool
socket_is_alive (
sock_t handle)
{
#if (defined (__UTYPE_BEOS))
/* BeOS 4.5 does not support the getsockopt() function */
int
rc;
rc = setsockopt ((SOCKET) handle, SOL_SOCKET, SO_NONBLOCK,
(void *) &ip_nonblock, sizeof (ip_nonblock));
return (rc == 0);
#elif (defined (DOES_SOCKETS))
int
socket_type,
rc;
argsize_t
socket_type_size = sizeof (SOCKET);
rc = getsockopt ((SOCKET) handle, SOL_SOCKET, SO_TYPE,
(char *) &socket_type, &socket_type_size);
return (rc == 0);
#else
return (FALSE);
#endif
}
/* ---------------------------------------------------------------------[<]-
Function: socket_error
Synopsis: Returns an errno value for the socket, or 0 if no error was
outstanding on the socket. This function is useful if you are handling
sockets using the select() function: this may return error indicators
on sockets, without precision on the type of error. This function will
return the precise error number. Errors like EINPROGRESS, EAGAIN, and
EWOULDBLOCK can usually be ignored or handled by retrying.
---------------------------------------------------------------------[>]-*/
int
socket_error (
sock_t handle)
{
#if (defined (DOES_SOCKETS))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -