Sockets and IO::Socket

Contents
A TCP client
A TCP server
Timeouts with IO::Select
Framing and safety

A TCP client

A socket is a file handle connected to another program. IO::Socket::INET ships with Perl and turns the connection details into one constructor call.

use strict; use warnings; use IO::Socket::INET; my $sock = IO::Socket::INET->new( PeerHost => "example.com", PeerPort => 80, Proto => "tcp", Timeout => 5, ) or die "connect failed: $!\n"; print $sock "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n"; while (my $line = <$sock>) { print $line; } close $sock;

This is HTTP by hand: the request line, one header, a blank line, then the response. Reading until end of file works here because the server closes the connection after one response — with HTTP/1.1 you would have to parse the length header instead.

A TCP server

A server binds a local port and then calls accept in a loop. Each accepted socket is a separate conversation, so the server can keep listening while it talks to a client.

my $server = IO::Socket::INET->new( LocalAddr => "127.0.0.1", LocalPort => 9000, Proto => "tcp", Listen => 5, Reuse => 1, ) or die "cannot listen on 9000: $!\n"; print "listening on 127.0.0.1:9000\n"; while (my $client = $server->accept) { $client->autoflush(1); print "client connected from ", $client->peerhost, "\n"; while (my $line = <$client>) { chomp $line; print $client "echo: $line\n"; last if $line eq "quit"; } close $client; }

Reuse => 1 lets you restart the server without waiting for the old port to leave the TIME_WAIT state. autoflush matters: without it the reply may sit in a buffer while the client waits forever.

This server handles one client at a time. For several at once, accept and then fork, or use a module that does the event loop for you, such as IO::Socket::INET plus IO::Select, or a framework like Mojo.

Timeouts with IO::Select

Reading from a socket blocks until data arrives. If the other side goes silent, your program waits. IO::Select asks whether a handle is readable within a time limit:

use IO::Select; my $sel = IO::Select->new($sock); if ($sel->can_read(5)) { my $line = <$sock>; print "got: $line"; } else { warn "no answer in 5 seconds\n"; }

The same object can watch many sockets at once and return the readable ones, which is a compact way to write a server for a handful of clients. can_write works the same way for sending.

Framing and safety

TCP is a stream of bytes, not a sequence of messages. One write can arrive as two reads, and two writes can arrive as one. A protocol has to mark where a message ends.

The simplest framing is a newline after every message, which is what many line-based protocols do. For arbitrary binary data, prefix the payload with its length and read exactly that many bytes:

my $len = pack("N", length $payload); print $sock $len, $payload;

Switch such a handle to binary mode with binmode $sock, otherwise Perl may translate line endings on some systems and corrupt the bytes. On the reading side, use read in a loop until you have the announced count.

Bind to 127.0.0.1 while learning. Binding to 0.0.0.0 exposes the service to the network, and a small echo server without authentication is an open relay for anything that finds the port. Check peerhost only if you control the network: addresses are easy to spoof.

Next: Databases with DBI

Article author: Arthur Isaev

Related articles
Perl
Perl course: zero to hero in 50 lessons
What is Perl and where it runs
Install Perl and check the version
Your first Perl script
The debugger as a REPL
Scalars and sigils
Numbers
Strings
Interpolation and quoting
Arrays
push, pop, shift and splice
Hashes
keys, values, exists and delete
Scalar and list context
Conditions and comparison
while, for, next and last
foreach and the default variable
Subroutines
Arguments in @_
References
Nested data structures
Regular expressions: match and anchors
Captures and named groups
Substitution with s///
split and join
grep and map
Sort and the Schwartzian transform
Read and write files
File tests and metadata
Directories and paths
die, warn and eval
Modules and Exporter
CPAN and cpanm
Objects with bless
Modern objects with Moo
Testing with Test::More
strict, warnings and diagnostics
Options with Getopt::Long
Environment and %ENV
system, backticks and pipes
One-liners with -n and -p
CSV and TSV processing
JSON with JSON::PP
HTTP clients with HTTP::Tiny
Sockets and IO::Socket
Databases with DBI
Capstone: todo CLI
Capstone: log report
Performance and profiling
Modern Perl tour
Hero roadmap: the whole course on one page
Install Perl on Windows 11
Install Perl on Ubuntu
Install Perl on Rocky Linux
Install Perl on macOS
Install Perl on FreeBSD
Perl in Docker

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.com
Write to info@aredel.com if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: