123456789_123456789_123456789_123456789_123456789_

Class: TCPSocket

Relationships & Source Files
Extension / Inclusion / Inheritance Descendants
Subclasses:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: IPSocket
Defined in: ext/socket/tcpsocket.c

Overview

TCPSocket represents a TCP/IP client socket.

A simple client may look like:

require 'socket'

s = TCPSocket.new 'localhost', 2000

while line = s.gets # Read lines from socket
  puts line         # and print them
end

s.close             # close socket when done

Class Attribute Summary

::BasicSocket - Inherited

.do_not_reverse_lookup

Gets the global do_not_reverse_lookup flag.

.do_not_reverse_lookup=

Sets the global do_not_reverse_lookup flag.

Class Method Summary

::IPSocket - Inherited

.getaddress

Lookups the IP address of host.

::BasicSocket - Inherited

.for_fd

Returns a socket object which contains the file descriptor, fd.

Instance Attribute Summary

::BasicSocket - Inherited

#do_not_reverse_lookup

Gets the do_not_reverse_lookup flag of basicsocket.

#do_not_reverse_lookup=

Sets the do_not_reverse_lookup flag of basicsocket.

Instance Method Summary

::IPSocket - Inherited

#addr

Returns the local address as an array which contains address_family, port, hostname and numeric_address.

#inspect

Return a string describing this ::IPSocket object.

#peeraddr

Returns the remote address as an array which contains address_family, port, hostname and numeric_address.

#recvfrom

Receives a message and return the message as a string and an address which the message come from.

::BasicSocket - Inherited

#close_read

Disallows further read using shutdown system call.

#close_write

Disallows further write using shutdown system call.

#connect_address

Returns an address of the socket suitable for connect in the local machine.

#getpeereid

Returns the user and group on the peer of the UNIX socket.

#getpeername

Returns the remote address of the socket as a sockaddr string.

#getsockname

Returns the local address of the socket as a sockaddr string.

#getsockopt

Gets a socket option.

#local_address

Returns an ::Addrinfo object for local address obtained by getsockname.

#recv

Receives a message.

#recv_nonblock

Receives up to maxlen bytes from socket using recvfrom(2) after O_NONBLOCK is set for the underlying file descriptor.

#recvmsg

recvmsg receives a message using recvmsg(2) system call in blocking manner.

#recvmsg_nonblock

recvmsg receives a message using recvmsg(2) system call in non-blocking manner.

#remote_address

Returns an ::Addrinfo object for remote address obtained by getpeername.

#send

send mesg via basicsocket.

#sendmsg

sendmsg sends a message using sendmsg(2) system call in blocking manner.

#sendmsg_nonblock

sendmsg_nonblock sends a message using sendmsg(2) system call in non-blocking manner.

#setsockopt

Sets a socket option.

#shutdown

Calls shutdown(2) system call.

#__recvmsg, #__recvmsg_nonblock, #__sendmsg, #__sendmsg_nonblock, #read_nonblock, #write_nonblock, #__read_nonblock, #__recv_nonblock, #__write_nonblock

Constructor Details

.new(remote_host, remote_port, local_host = nil, local_port = nil, resolv_timeout: nil, connect_timeout: nil, fast_fallback: true)

Opens a TCP connection to remote_host on remote_port. If local_host and local_port are specified, then those parameters are used on the local end to establish the connection.

Starting from Ruby 3.4, this method operates according to the Happy Eyeballs Version 2 (RFC 8305) algorithm by default, except on Windows.

To make it behave the same as in Ruby 3.3 and earlier, explicitly specify the option fast_fallback:false.

Happy Eyeballs Version 2 is not provided on Windows, and it behaves the same as in Ruby 3.3 and earlier.

:resolv_timeout

Specifies the timeout in seconds from when the hostname resolution starts.

:connect_timeout

This method sequentially attempts connecting to all candidate destination addresses.
The connect_timeout specifies the timeout in seconds from the start of the connection attempt to the last candidate.
By default, all connection attempts continue until the timeout occurs.
When fast_fallback:false is explicitly specified,
a timeout is set for each connection attempt and any connection attempt that exceeds its timeout will be canceled.

:fast_fallback

Enables the Happy Eyeballs Version 2 algorithm (enabled by default).

Happy Eyeballs Version 2

Happy Eyeballs Version 2 (RFC 8305) is an algorithm designed to improve client socket connectivity.
It aims for more reliable and efficient connections by performing hostname resolution and connection attempts in parallel, instead of serially.

Starting from Ruby 3.4, this method operates as follows with this algorithm except on Windows:

  1. Start resolving both IPv6 and IPv4 addresses concurrently.

  2. Start connecting to the one of the addresses that are obtained first.
    If IPv4 addresses are obtained first, the method waits 50 ms for IPv6 name resolution to prioritize IPv6 connections.

  3. After starting a connection attempt, wait 250 ms for the connection to be established.
    If no connection is established within this time, a new connection is started every 250 ms
    until a connection is established or there are no more candidate addresses.
    (Although RFC 8305 strictly specifies sorting addresses,
    this method only alternates between IPv6 / IPv4 addresses due to the performance concerns)

  4. Once a connection is established, all remaining connection attempts are canceled.

[ GitHub ]

  
# File 'ext/socket/tcpsocket.c', line 53

static VALUE
tcp_init(int argc, VALUE *argv, VALUE sock)
{
    VALUE remote_host, remote_serv;
    VALUE local_host, local_serv;
    VALUE opt;
    static ID keyword_ids[4];
    VALUE kwargs[4];
    VALUE resolv_timeout = Qnil;
    VALUE connect_timeout = Qnil;
    VALUE fast_fallback = Qnil;
    VALUE test_mode_settings = Qnil;

    if (!keyword_ids[0]) {
        CONST_ID(keyword_ids[0], "resolv_timeout");
        CONST_ID(keyword_ids[1], "connect_timeout");
        CONST_ID(keyword_ids[2], "fast_fallback");
        CONST_ID(keyword_ids[3], "test_mode_settings");
    }

    rb_scan_args(argc, argv, "22:", &remote_host, &remote_serv,
                        &local_host, &local_serv, &opt);

    if (!NIL_P(opt)) {
        rb_get_kwargs(opt, keyword_ids, 0, 4, kwargs);
        if (kwargs[0] != Qundef) { resolv_timeout = kwargs[0]; }
        if (kwargs[1] != Qundef) { connect_timeout = kwargs[1]; }
        if (kwargs[2] != Qundef) { fast_fallback = kwargs[2]; }
        if (kwargs[3] != Qundef) { test_mode_settings = kwargs[3]; }
    }

    if (fast_fallback == Qnil) {
        VALUE socket_class = rb_const_get(rb_cObject, rb_intern("Socket"));
        ID var_id = rb_intern("@tcp_fast_fallback");
        fast_fallback = rb_ivar_get(socket_class, var_id);
        if (fast_fallback == Qnil) fast_fallback = Qtrue;
    }

    return rsock_init_inetsock(sock, remote_host, remote_serv,
                               local_host, local_serv, INET_CLIENT,
                               resolv_timeout, connect_timeout, fast_fallback,
                               test_mode_settings);
}

Class Method Details

.gethostbyname(hostname) ⇒ Array, ...

Use Addrinfo.getaddrinfo instead. This method is deprecated for the following reasons:

  • The 3rd element of the result is the address family of the first address. The address families of the rest of the addresses are not returned.

  • gethostbyname() may take a long time and it may block other threads. (GVL cannot be released since gethostbyname() is not thread safe.)

  • This method uses gethostbyname() function already removed from POSIX.

This method lookups host information by hostname.

TCPSocket.gethostbyname("localhost")
#=> ["localhost", ["hal"], 2, "127.0.0.1"]
[ GitHub ]

  
# File 'ext/socket/tcpsocket.c', line 122

static VALUE
tcp_s_gethostbyname(VALUE obj, VALUE host)
{
    rb_warn("TCPSocket.gethostbyname is deprecated; use Addrinfo.getaddrinfo instead.");
    struct rb_addrinfo *res =
        rsock_addrinfo(host, Qnil, AF_UNSPEC, SOCK_STREAM, AI_CANONNAME);
    return rsock_make_hostent(host, res, tcp_sockaddr);
}