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

📄 sflsock.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
#   if (defined (__UTYPE_BEOS))
    return (errno);
#   else
    return (getsockopt ((SOCKET) handle, SOL_SOCKET, SO_ERROR, 0, 0));
#   endif
#else
    return (0);
#endif
}


/*  ---------------------------------------------------------------------[<]-
    Function: accept_socket

    Synopsis: Accepts a connection on a specified master socket.  If you
    do not want to wait on this call, use select() to poll the socket until
    there is an incoming request, then call accept_socket.  Returns the
    number of the new slave socket, or INVALID_SOCKET if there was an error
    on the accept call.  You can handle errors as fatal except for EAGAIN
    which indicates that the operation would cause a non-blocking socket to
    block (treat EWOULDBLOCK in the same way).
    ---------------------------------------------------------------------[>]-*/

sock_t
accept_socket (
    sock_t master_socket)
{
#if (defined (DOES_SOCKETS))
    sock_t
        slave_socket;                   /*  Connected slave socket           */
    struct sockaddr_in
        sin;                            /*  Address of connecting party      */
    argsize_t
        sin_length;                     /*  Length of address                */

    connect_error_value = IP_NOERROR;   /*  Assume no errors                 */

    sin_length = (int) sizeof (sin);
    slave_socket = accept ((SOCKET) master_socket,
                          (struct sockaddr *) &sin, &sin_length);

    /*  On non-Windows systems, accept returns -1 in case of error, which    */
    /*  is the same as INVALID_SOCKET.                                       */
#   if (defined (__WINDOWS__))
    if (slave_socket == INVALID_SOCKET)
      {
        int sock_errno = WSAGetLastError ();
        if (sock_errno == WSAEWOULDBLOCK || sock_errno == WSAEINPROGRESS)
            errno = EAGAIN;
      }
#   endif
    if (slave_socket != INVALID_SOCKET)
      {
        prepare_socket (slave_socket);
        ip_sockets++;
      }
    return (slave_socket);
#else
    connect_error_value = IP_NOSOCKETS;
    return (INVALID_SOCKET);            /*  Sockets not supported            */
#endif
}


/*  ---------------------------------------------------------------------[<]-
    Function: connect_error

    Synopsis:
    Returns the last error code from one of the connection functions.  For
    portability in a multithreaded environment, call immediately after the
    call to the connection function.
    ---------------------------------------------------------------------[>]-*/

int
connect_error (void)
{
    return (connect_error_value);
}


/*  ---------------------------------------------------------------------[<]-
    Function: get_sock_addr

    Synopsis: Builds an address block (struct sockaddr_in) for the local
    end of the specified connected socket.  Returns 0 if okay, SOCKET_ERROR
    if there was an error.  If the name argument is not null, looks-up the
    host name and returns it.  The name is truncated to namesize characters,
    including a trailing null character.
    ---------------------------------------------------------------------[>]-*/

int
get_sock_addr (
    sock_t handle,                      /*  Socket to get address for        */
    struct sockaddr_in *sin,            /*  Block for formatted address      */
    char *name,                         /*  Buffer for host name, or NULL    */
    int namesize                        /*  Size of host name buffer         */
)
{
#if (defined (DOES_SOCKETS))
    int
        rc;                             /*  Return code from call            */
    struct hostent
        *phe;                           /*  Host information entry           */
    argsize_t
        sin_length;                     /*  Length of address                */

    ASSERT (sin);

    /*  Get address for local connected socket                               */
    sin_length = sizeof (struct sockaddr_in);

    rc = getsockname ((SOCKET) handle, (struct sockaddr *) sin, &sin_length);

    /*  Translate into host name string, only if wanted                      */
    if (name != NULL && rc == 0)
      {
        phe = gethostbyaddr ((char *) &sin-> sin_addr,
                             sizeof (sin-> sin_addr), AF_INET);
        if (phe)
          {
            strncpy (name, phe-> h_name, namesize);
            name [namesize - 1] = '\0';
          }
      }
#   if (defined (__WINDOWS__))
    return (win_error (rc));
#   else
    return (rc);
#   endif
#else
    return ((int) SOCKET_ERROR);        /*  Sockets not supported            */
#endif
}


/*  ---------------------------------------------------------------------[<]-
    Function: get_peer_addr

    Synopsis: Builds an address block (struct sockaddr_in) for the remote
    end of the specified connected socket.  Returns 0 if okay, SOCKET_ERROR
    if there was an error.  If the name argument is not null, looks-up the
    host name and returns it.  The name is truncated to namesize characters,
    including a trailing null character.
    ---------------------------------------------------------------------[>]-*/

int
get_peer_addr (
    sock_t handle,                      /*  Socket to get address for        */
    struct sockaddr_in *sin,            /*  Block for formatted address      */
    char *name,                         /*  Buffer for host name, or NULL    */
    int namesize                        /*  Size of host name buffer         */
)
{
#if (defined (DOES_SOCKETS))
    int
        rc;                             /*  Return code from call            */
    struct hostent
        *phe;                           /*  Host information entry           */
    argsize_t
        sin_length;                     /*  Length of address                */

    ASSERT (sin);

    /*  Get address for connected socket peer                                */
    sin_length = sizeof (struct sockaddr_in);
    rc = getpeername ((SOCKET) handle, (struct sockaddr *) sin, &sin_length);

    /*  Translate into host name string, only if wanted                      */
    if (name != NULL && rc == 0)
      {
        phe = gethostbyaddr ((char *) &sin-> sin_addr,
                             sizeof (sin-> sin_addr), AF_INET);
        if (phe)
          {
            strncpy (name, phe-> h_name, namesize);
            name [namesize - 1] = '\0';
          }
      }
#   if (defined (__WINDOWS__))
    return (win_error (rc));
#   else
    return (rc);
#   endif
#else
    return ((int) SOCKET_ERROR);        /*  Sockets not supported            */
#endif
}


/*  ---------------------------------------------------------------------[<]-
    Function: read_TCP

    Synopsis:
    Reads data from the socket.  On UNIX, VMS, OS/2, passes through to the
    standard read function; some other systems have particular ways of
    accessing sockets.  If there is an error on the read this function
    returns SOCKET_ERROR.  You can handle errors (in sockerrno) as fatal except
    for EAGAIN which indicates that the operation would cause a non-blocking
    socket to block, and EPIPE or ECONNRESET which indicate that the socket
    was closed at the other end.  Treat EWOULDBLOCK as EAGAIN.
    ---------------------------------------------------------------------[>]-*/

int
read_TCP (
    sock_t handle,                      /*  Socket handle                    */
    void *buffer,                       /*  Buffer to receive data           */
    size_t length                       /*  Maximum amount of data to read   */
)
{
#if (defined (DOES_SOCKETS))
#   if (defined (__UTYPE_BEOS))
    return (recv ((SOCKET) handle, buffer, length, 0));

#   elif (defined (__UNIX__) || defined (__VMS__) || defined (__OS2__))
    return (read ((SOCKET) handle, buffer, length));

#   elif (defined (__WINDOWS__))
    int
        rc;                             /*  Return code from call            */

    ASSERT (buffer);
    rc = recv ((SOCKET) handle, buffer, length, 0);
    return (win_error (rc));
#   else
#       error "No code for function body."
#   endif
#else
    return ((int) SOCKET_ERROR);        /*  Sockets not supported            */
#endif
}


#if (defined (__WINDOWS__))
/*  -------------------------------------------------------------------------
 *  win_error -- internal
 *
 *  For Winsockets only: fetches real error code and sticks it in errno,
 *  if the return code from the last call was SOCKET_ERROR.  Returns rc.
 */

static int
win_error (int rc)
{
    if (rc == (int) SOCKET_ERROR)
        errno = winsock_last_error ();        

    return (rc);
}
#endif


/*  ---------------------------------------------------------------------[<]-
    Function: write_TCP

    Synopsis:
    Writes data to the socket.  On UNIX, VMS, OS/2, calls the standard
    write function; some other systems have particular ways of accessing
    sockets.  If there is an error on the write this function returns
    SOCKET_ERROR.  You can handle errors (in sockerrno) as fatal except for
    EAGAIN which indicates that the operation would cause a non-blocking
    socket to block, and EPIPE or ECONNRESET which indicate that the socket
    was closed at the other end.  Treat EWOULDBLOCK as EAGAIN.
    ---------------------------------------------------------------------[>]-*/

int
write_TCP (
    sock_t handle,                      /*  Socket handle                    */
    const void *buffer,                 /*  Buffer containing data           */
    size_t length                       /*  Amount of data to write          */
)
{
#if (defined (DOES_SOCKETS))
#   if (defined (__UTYPE_BEOS))
    return (send ((SOCKET) handle, buffer, length, 0));

#   elif (defined (__UNIX__) || defined (__VMS__) || defined (__OS2__))
    return (write ((SOCKET) handle, buffer, length));

#   elif (defined (__WINDOWS__))
    int
        rc;                             /*  Return code from call            */

    ASSERT (buffer);
    rc = send ((SOCKET) handle, buffer, length, 0);
    return (win_error (rc));
#   else
#       error "No code for function body."
#   endif
#else
    return ((int) SOCKET_ERROR);        /*  Sockets not supported            */
#endif
}


/*  ---------------------------------------------------------------------[<]-
    Function: read_UDP

    Synopsis:
    Reads data from a connected or unconnected UDP socket.  To prepare a
    connected UDP socket you call connect_UDP ().  This makes a connection
    to a specific port on a specific host, and returns a socket handle.
    When you call this function with a null value for the address argument,
    it assumes you are using a connected UDP socket.

    To prepare an unconnected UDP socket, call create_socket () with the
    string "udp" as argument.  This returns a sock_t handle that you can
    use in this function.  If you use an unconnected UDP socket you must
    provide an address structure.  The function places the remote host and
    port in this structure.  This lets you reply using write_UDP ().

    Generally a server can use unconnected sockets, and a client can use
    connected sockets.  You can also format an address for a specific host
    and port using the address_end_point () function.

    If there is an error on the read this function returns SOCKET_ERROR.
    You can handle errors (in sockerrno) as fatal except for EAGAIN which
    indicates that the operation would cause a non-blocking socket to block.
    Treat EWOULDBLOCK as EAGAIN.
    ---------------------------------------------------------------------[>]-*/

int
read_UDP (
    sock_t handle,                      /*  Socket handle                    */
    void *buffer,                       /*  Buffer to receive data           */
    size_t length,                      /*  Maximum amount of data to read   */
    const struct sockaddr_in *sin       /*  Block for address, or null       */
)
{
#if (defined (DOES_SOCKETS))
    argsize_t
        sin_length;                     /*  Length of address                */
    int
        flags = 0,                      /*  Flags for call                   */
        rc;                             /*  Return code from call            */

    ASSERT (buffer);
    ASSERT (sin);
    sin_length = (int) sizeof (*sin);
    if (sin)
        /*  Read from unconnected UDP socket; we accept the address of the   */
        /*  sending party in the sin argument.                               */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -