=begin pod :kind("Type") :subkind("class") :category("domain-specific")

=TITLE class IO::Socket::INET

=SUBTITLE TCP Socket

=for code :preamble<role IO::Socket {}>
class IO::Socket::INET does IO::Socket {}

C<IO::Socket::INET> provides TCP sockets, both the server and the client side.

For UDP support, please see L<IO::Socket::Async|/type/IO::Socket::Async>.

Here is an example of a very simplistic "echo" server that listens on
C<localhost>, port C<3333>:

=begin code
my $listen = IO::Socket::INET.new( :listen,
                                   :localhost<localhost>,
                                   :localport(3333) );
loop {
    my $conn = $listen.accept;
    try {
        while my $buf = $conn.recv(:bin) {
            $conn.write: $buf;
        }
    }
    $conn.close;

    CATCH {
          default { .payload.say;      }
    }

}
=end code

And a client that connects to it, and prints out what the server answers:

=begin code
my $conn = IO::Socket::INET.new( :host<localhost>,
                                 :port(3333) );
$conn.print: 'Hello, Raku';
say $conn.recv;
$conn.close;
=end code

Please bear in mind that this is a synchronous connection; an attempt by any of the nodes to write without the other reading will produce an C<Could not receive data from socket: Connection reset by peer> error.

=head1 Methods

=head2 method new

=for code :skip-test<compile time error>
multi method new(
        :$host,
        :$port,
        :$family = PF_INET,
        :$encoding = 'utf-8',
        :$nl-in = "\r\n",
    --> IO::Socket::INET:D)
multi method new(
        :$localhost,
        :$localport,
        :$family = PF_INET,
        :$listen,
        :$encoding = 'utf-8',
        :$nl-in = "\r\n",
    --> IO::Socket::INET:D)

Creates a new socket.

If C<:$listen> is True, creates a new socket that listen on C<:$localhost>
(which can be an IP address or a domain name) on port C<:$localport>; in other words
the C<:$listen> flag determines the I<server mode> of the socket.
Otherwise (i.e., C<:$listen> is C<False>), the new socket opens immediately
a connection to C<:$host> on port C<:$port>.

C<:$family> defaults to C<PF_INET> constant for IPv4, and can be set
to C<PF_INET6> constant for IPv6.

For text operations (such as L<#method lines> and L<#method get>),
C<:$encoding> specifies the encoding, and C<:$nl-in> determines
the character(s) that separate lines.

=head1 Methods

=head2 method get

    method get()

Reads a line from the socket and returns it as of type L<Str|/type/Str>.
Return L<Nil|/type/Nil> on end-of-file (EOF).

=head2 method lines

    method lines()

Returns a lazy list of lines read from the socket.

=head2 method accept

    method accept()

In listen/server mode, waits for a new incoming connection.
Once a new connection is established, an C<IO::Socket::INET>
instance (or a subclass instance) for consuming
the connection is returned.

=end pod
