--- name: getpeername signature: 'getpeername SOCKET' since: 5.0 status: documented categories: ["Sockets"] --- ```{index} single: getpeername; Perl built-in ``` *[Sockets](../perlfunc-by-category)* # getpeername Return the address of the remote end of a connected socket. `getpeername` asks the kernel who is on the other side of `SOCKET` and returns the answer as a packed `sockaddr` byte string — the same shape [`connect`](connect) took and the same shape [`accept`](accept) returned. You then hand that byte string to an unpacker from [`Socket`](../../Socket) (or [`Socket::unpack_sockaddr_in`](../../Socket/unpack_sockaddr_in), [`Socket::unpack_sockaddr_in6`](../../Socket/unpack_sockaddr_in6), [`Socket::unpack_sockaddr_un`](../../Socket/unpack_sockaddr_un)) to pull out the port, address, or path. This is the companion to [`getsockname`](getsockname), which returns the **local** end of the same socket. ## Synopsis ```perl use Socket; my $peer = getpeername SOCKET; my ($port, $iaddr) = unpack_sockaddr_in($peer); ``` ## What you get back A packed `sockaddr` byte string on success, [`undef`](undef) on failure (with [`$!`](../perlvar) set — typically `ENOTCONN` when the socket has no peer, or `EBADF` when `SOCKET` is not an open file descriptor). The byte string is opaque. Its layout depends on the socket's address family; always decode it with an unpacker that matches the family you expect: - `AF_INET` → [`Socket::unpack_sockaddr_in`](../../Socket/unpack_sockaddr_in) returns `($port, $iaddr)` where `$iaddr` is the 4-byte packed IPv4 address. - `AF_INET6` → [`Socket::unpack_sockaddr_in6`](../../Socket/unpack_sockaddr_in6) returns `($port, $iaddr, $scope_id, $flowinfo)`. - `AF_UNIX` → [`Socket::unpack_sockaddr_un`](../../Socket/unpack_sockaddr_un) returns the peer's filesystem path. If you do not know the family at the call site, ask [`Socket::sockaddr_family`](../../Socket/sockaddr_family) first: ```perl my $peer = getpeername $sock; my $family = sockaddr_family($peer); ``` ## Global state it touches `getpeername` reads the file-descriptor state of `SOCKET`. It sets [`$!`](../perlvar) on failure and does not otherwise touch interpreter globals. It does not interact with [`$_`](../perlvar), the selected filehandle, or output separators. ## Examples Look up the remote IPv4 peer of a client-side TCP socket and render it in dotted-quad form: ```perl use Socket; my $peer = getpeername($sock) or die "getpeername: $!"; my ($port, $iaddr) = unpack_sockaddr_in($peer); printf "peer is %s:%d\n", inet_ntoa($iaddr), $port; ``` Server side: every socket returned by [`accept`](accept) is already connected, and [`accept`](accept) itself hands back the peer address. `getpeername` is useful later, when that packed address has not been kept around: ```perl while (my $client = accept(my $conn, $listen)) { handle($conn); } sub handle { my ($conn) = @_; my $peer = getpeername($conn) or return; my ($port, $iaddr) = unpack_sockaddr_in($peer); warn "request from ", inet_ntoa($iaddr), ":$port\n"; # ... } ``` Resolve the peer back to a hostname — note that this issues a blocking DNS lookup: ```perl use Socket; my $peer = getpeername($sock); my ($port, $iaddr) = unpack_sockaddr_in($peer); my $name = gethostbyaddr($iaddr, AF_INET); print "connected to ", $name // inet_ntoa($iaddr), "\n"; ``` Mixed IPv4 / IPv6 code — decode generically via the address family: ```perl use Socket qw(sockaddr_family unpack_sockaddr_in unpack_sockaddr_in6 AF_INET AF_INET6 inet_ntop); my $peer = getpeername($sock) or die "getpeername: $!"; my $fam = sockaddr_family($peer); if ($fam == AF_INET) { my ($port, $iaddr) = unpack_sockaddr_in($peer); printf "v4 %s:%d\n", inet_ntop(AF_INET, $iaddr), $port; } elsif ($fam == AF_INET6) { my ($port, $iaddr) = unpack_sockaddr_in6($peer); printf "v6 [%s]:%d\n", inet_ntop(AF_INET6, $iaddr), $port; } ``` Probing whether a socket is connected at all — the `ENOTCONN` path is the well-defined way to ask: ```perl if (defined getpeername($sock)) { # connected } else { # $! == ENOTCONN for an unconnected socket } ``` ## Edge cases - **Unconnected socket**: a socket that has been [`socket`](socket)'d but not yet [`connect`](connect)'d or [`accept`](accept)'d has no peer. `getpeername` returns [`undef`](undef) and sets [`$!`](../perlvar) to `ENOTCONN`. - **Non-socket filehandle**: passing a plain file or pipe yields [`undef`](undef) with [`$!`](../perlvar) set to `ENOTSOCK`. - **Closed or invalid filehandle**: returns [`undef`](undef) with [`$!`](../perlvar) set to `EBADF`. Under `use warnings` a `getpeername() on closed socket` warning is emitted. - **Datagram sockets**: `getpeername` only returns an address when the `SOCK_DGRAM` socket has been [`connect`](connect)'d to a default peer; otherwise it fails with `ENOTCONN` even though the socket is usable via [`recv`](recv) / [`send`](send). - **`AF_UNIX` with an unbound peer**: a Unix-domain socket whose peer never called [`bind`](bind) returns a packed `sockaddr_un` with an empty path. [`Socket::unpack_sockaddr_un`](../../Socket/unpack_sockaddr_un) gives back the empty string. - **After [`shutdown`](shutdown)**: `getpeername` still succeeds as long as the descriptor is open; shutdown tears down data flow, not the kernel's record of the peer. - **SOCKET is a parsed filehandle token**: like other socket built-ins, the argument is parsed as a filehandle, not evaluated as a general expression. `getpeername $handles[0]` is a syntax error; use a scalar holding the handle, or [`*{...}`](../perlop) dereferencing. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`getsockname`](getsockname) — mirror call that returns the **local** end of the same socket; pairs with `getpeername` when logging both ends of a connection - [`accept`](accept) — already hands you the peer address for a freshly accepted server-side socket; use `getpeername` later when that address was not retained - [`connect`](connect) — the call that establishes the peer in the first place; the address you pass to [`connect`](connect) is what `getpeername` will hand back afterwards - [`Socket`](../../Socket) — provides the unpackers ([`unpack_sockaddr_in`](../../Socket/unpack_sockaddr_in), [`unpack_sockaddr_in6`](../../Socket/unpack_sockaddr_in6), [`unpack_sockaddr_un`](../../Socket/unpack_sockaddr_un)) and [`sockaddr_family`](../../Socket/sockaddr_family) needed to interpret the returned byte string - [`gethostbyaddr`](gethostbyaddr) — turns the packed IPv4 address from the unpacker into a hostname - [`$!`](../perlvar) — carries the reason on failure (`ENOTCONN`, `ENOTSOCK`, `EBADF`)