⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sflsock.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
        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 + -