| iMatix home page
| << | < | > | >>
SFL Logo SFL
Version 2.10

 

connect_socket

#include "sflsock.h"
sock_t
connect_socket (
    const char *host,                   /*  Name of host, "" = localhost     */
    const char *service,                /*  Service name or port as string   */
    const char *protocol,               /*  Protocol "tcp" or "udp"          */
    const struct sockaddr_in *host_addr, /* Socket address structure         */
    int retries_left,                   /*  Max. number of retries           */
    int retry_delay                     /*  Delay between retries            */
)

Synopsis

Makes a connection to a remote TCP or UDP port. This allows a client program to start sending information to a server. Used by the connect_TCP and connect_UDP functions. Returns a socket number or INVALID_SOCKET. If it returns INVALID_SOCKET, you can get the reason for the error by calling connect error (). This may be one of:
IP NOSOCKETS Sockets not supported on this system
IP BADHOST Host is not known
IP BADPROTOCOL Cannot understand protocol name
IP SOCKETERROR Cannot open a socket
IP CONNECTERROR Cannot connect socket
Always blocks until the connection has been made; i.e. when this function returns you can start to read and write on the socket. The host name may be a full name, NULL or "" meaning the current host, or a dotted-decimal number. The service may be a defined service, e.g. "echo", or a port number, specified as an ASCII string. Alternatively, both these values may be NULL or "", in which case the function uses the host_addr argument to supply an address. If you want to build the host_addr structure yourself, use build sockaddr(). Single-threaded clients may set ip_nonblock to FALSE and block on all read and write operations. They may use select() if they need to be able to time-out during reading/writing. Multi- threaded servers should set ip_nonblock to TRUE, and use select() to multiplex socket access. When ip_nonblock is TRUE, connect calls will return immediately, and the server should use select() to wait until the socket is ready for writing. On some systems (early Linux?), the select() call will fail in this situation. If you compile with -DBLOCKING_CONNECT, connects are done synchronously in all cases.

Examples

    struct sockaddr_in
        host_addr;
    sock_t
        handle;
    build_sockaddr (&host_addr, 32_bit_host, 16_bit_port);
    handle = connect_socket (NULL, NULL, "tcp", &host_addr, 3, 0);

Source Code - (sflsock.c)

{
#if (defined (DOES_SOCKETS))
    struct sockaddr_in
        sin;                            /*  Internet end-point address       */
    sock_t
        handle = 0;                     /*  Created socket                   */
    int
        rc;                             /*  Return code from call            */
    Bool
        old_nonblock;                   /*  Create non-blocking sockets      */

    connect_error_value = IP_NOERROR;   /*  Assume no errors                 */

    /*  Format sockaddr_in port and hostname, and quit if that failed        */
    if (service && strused (service))
      {
        ASSERT (protocol && *protocol);
        if (address end point (host, service, protocol, &sin))
            return (INVALID_SOCKET);
      }
    else
      {
        ASSERT (host_addr);
        sin = *host_addr;               /*  Fast connect requested           */
      }
    /*  Connect socket and maybe retry a few times...                        */
    old_nonblock = ip_nonblock;
#   if (defined (BLOCKING_CONNECT))
    ip_nonblock = FALSE;                /*  Block on this socket             */
#   endif

    while (retries_left)
      {
        handle = create socket (protocol);
        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
}

| << | < | > | >> iMatix Copyright © 1996-99 iMatix Corporation