Sockets

connect#

Initiate a connection from a socket to a remote address.

connect is the client-side half of the socket handshake. Given a SOCKET that was created with socket and a packed address NAME in the form the socket’s address family expects, it asks the kernel to establish a connection to that peer. It is a thin wrapper over the connect(2) system call and inherits every one of that call’s blocking, non-blocking, and error semantics.

Synopsis#

connect SOCKET, NAME

What you get back#

Truthy (1) on success, false on failure with $! set to the system error. Always check the return value — there is no useful default behaviour when a connection attempt fails:

connect($sock, $peer)
    or die "connect to $host:$port failed: $!";

Global state it touches#

  • $! is set to the kernel’s errno on failure. Interpret it against the Errno constants, not by string value — the stringified message is locale-dependent.

  • The socket handle itself carries the connection state; no other special variables are involved.

Building NAME: it’s a packed struct, not a string#

The second argument is not a "host:port" string. It’s a packed sockaddr in the exact byte layout the kernel expects for the socket’s address family. Build it with the helpers from Socket:

  • sockaddr_in($port, $inaddr) for IPv4 — $inaddr from inet_aton or inet_pton.

  • sockaddr_in6($port, $in6addr) for IPv6 — $in6addr from inet_pton(AF_INET6, ...).

  • sockaddr_un($path) for Unix-domain sockets.

Hand-packing with pack works, but there is no reason to do so when Socket already exports the right builders.

Examples#

A plain IPv4 TCP client:

use Socket;

socket(my $sock, PF_INET, SOCK_STREAM, getprotobyname("tcp"))
    or die "socket: $!";

my $addr = sockaddr_in(80, inet_aton("93.184.216.34"));
connect($sock, $addr)
    or die "connect: $!";

print $sock "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";

Modern address-family-agnostic client via getaddrinfo:

use Socket qw(getaddrinfo SOCK_STREAM);

my ($err, @res) = getaddrinfo("example.com", "80",
                              { socktype => SOCK_STREAM });
die "getaddrinfo: $err" if $err;

my $sock;
for my $ai (@res) {
    socket($sock, $ai->{family}, $ai->{socktype}, $ai->{protocol})
        or next;
    last if connect($sock, $ai->{addr});
    close $sock;
    undef $sock;
}
defined $sock or die "could not connect to any address";

A Unix-domain client:

use Socket;

socket(my $sock, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!";
connect($sock, sockaddr_un("/tmp/my.sock"))
    or die "connect: $!";

Non-blocking connect with a timeout via select — the idiomatic way to bound a connect attempt in pure Perl:

use Socket;
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
use Errno qw(EINPROGRESS);

socket(my $sock, PF_INET, SOCK_STREAM, 0) or die "socket: $!";
my $flags = fcntl($sock, F_GETFL, 0);
fcntl($sock, F_SETFL, $flags | O_NONBLOCK);

my $ok = connect($sock, sockaddr_in(80, inet_aton("93.184.216.34")));
if (!$ok && $! == EINPROGRESS) {
    my $w = '';
    vec($w, fileno($sock), 1) = 1;
    my $n = select(undef, $w, undef, 5.0);   # 5-second timeout
    $n > 0 or die "connect timed out";
    # Check SO_ERROR to see whether the async connect succeeded:
    my $err = unpack("i", getsockopt($sock, SOL_SOCKET, SO_ERROR));
    $err == 0 or die "connect: " . do { local $! = $err; "$!" };
}

Edge cases#

  • Address-family mismatch. If NAME was packed for a different family than the socket was created with (e.g. sockaddr_in against a PF_INET6 socket), connect fails with EAFNOSUPPORT or EINVAL. The packed bytes carry the family; the kernel checks.

  • Already connected. Calling connect on a stream socket that is already connected fails with EISCONN.

  • Connectionless sockets. On SOCK_DGRAM / SOCK_RAW sockets, connect does not exchange packets; it records a default peer so that subsequent send / recv calls can omit the address. It can be called again with a new NAME, or cleared by calling with an AF_UNSPEC sockaddr.

  • Non-blocking sockets. If the socket is in non-blocking mode, a TCP connect typically returns false with $! set to EINPROGRESS. The connection is not yet established. Wait for the socket to become writable (via select or your event loop), then read SO_ERROR with getsockopt to obtain the final status. A zero SO_ERROR means the connection is up; anything else is the real failure code.

  • Signals interrupting the call. A blocking connect can return false with $! set to EINTR if a signal handler ran. The socket is still connecting in the background; you must wait on writability and check SO_ERROR as in the non-blocking case — do not retry the connect call, that yields EALREADY.

  • Unbound source address. If bind was not called first, the kernel picks a source address and ephemeral port automatically. The common case is to skip bind on the client.

  • Closed or unopened socket. Fails with EBADF.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • socket — create the endpoint that connect operates on

  • bind — pin the local address before connecting; rarely needed on a client

  • accept — the server-side counterpart to connect

  • getpeername — recover the peer address of a connected socket

  • shutdown — close one direction of a connected socket without releasing the descriptor

  • Socket — packers (sockaddr_in, sockaddr_un, …) and constants (PF_INET, SOCK_STREAM, …) used to build arguments

  • Errno — symbolic constants for comparing $! against EINPROGRESS, EISCONN, ECONNREFUSED, …