Skip to content

Instantly share code, notes, and snippets.

@mahrous-amer
Created July 3, 2025 06:38
Show Gist options
  • Save mahrous-amer/08bf9c80b9582afb682d5a5af1152c79 to your computer and use it in GitHub Desktop.
Save mahrous-amer/08bf9c80b9582afb682d5a5af1152c79 to your computer and use it in GitHub Desktop.
Perl script for TCP server and client communication. Supports server and client modes via command-line options. Server echoes client input, supports multiple connections, and includes SO_REUSEADDR. Client reads server responses. Features include configurable host/port, non-blocking I/O, and detailed connection logging. Usage: `--mode=server|clie…
#!/usr/bin/perl -w
use strict;
use Socket;
use Getopt::Long;
use IO::Handle;
# Configuration
my $default_port = 7890;
my $default_host = 'localhost';
my $backlog = 5;
my $buffer_size = 1024;
# Command-line options
my ($port, $host, $mode, $help);
GetOptions(
'port=i' => \$port,
'host=s' => \$host,
'mode=s' => \$mode,
'help' => \$help
) or die "Usage: $0 [--port=<port>] [--host=<host>] [--mode=server|client] [--help]\n";
if ($help) {
print <<'HELP';
Usage: $0 [options]
Options:
--port=<port> Port to use (default: 7890)
--host=<host> Host for client mode (default: localhost)
--mode=<mode> Mode: 'server' or 'client' (required)
--help Show this help message
HELP
exit 0;
}
$port ||= $default_port;
$host ||= $default_host;
$mode or die "Mode must be specified (--mode=server or --mode=client)\n";
$mode = lc($mode);
# Common socket setup
my $proto = getprotobyname('tcp') or die "Can't get protocol: $!\n";
sub run_client {
my ($host, $port) = @_;
# Create socket
socket(my $socket, PF_INET, SOCK_STREAM, $proto)
or die "Can't create socket: $!\n";
# Connect to server
my $server_addr = inet_aton($host) or die "Invalid host: $host\n";
connect($socket, pack_sockaddr_in($port, $server_addr))
or die "Can't connect to $host:$port: $!\n";
# Set socket to non-blocking
$socket->autoflush(1);
# Read and print server response
while (my $line = <$socket>) {
chomp $line;
print "Received: $line\n";
}
close $socket or warn "Client close failed: $!\n";
}
sub run_server {
my ($port) = @_;
# Create socket
socket(my $socket, PF_INET, SOCK_STREAM, $proto)
or die "Can't create socket: $!\n";
# Set socket options
setsockopt($socket, SOL_SOCKET, SO_REUSEADDR, 1)
or die "Can't set SO_REUSEADDR: $!\n";
# Bind and listen
bind($socket, pack_sockaddr_in($port, inet_aton('0.0.0.0')))
or die "Can't bind to port $port: $!\n";
listen($socket, $backlog) or die "Listen failed: $!\n";
print "Server started on port $port\n";
# Handle connections
while (my $client_addr = accept(my $client, $socket)) {
$client->autoflush(1);
# Get client info
my ($client_port, $client_ip) = unpack_sockaddr_in($client_addr);
my $client_host = gethostbyaddr($client_ip, AF_INET) || inet_ntoa($client_ip);
print "Connection from $client_host:$client_port\n";
# Send response
print $client "Welcome to the server at ", scalar(localtime), "\n";
# Echo client input
while (my $data = <$client>) {
chomp $data;
last if $data eq 'quit';
print $client "Echo: $data\n";
print "Received from $client_host: $data\n";
}
close $client or warn "Client close failed: $!\n";
}
close $socket or warn "Server close failed: $!\n";
}
# Run in specified mode
if ($mode eq 'client') {
run_client($host, $port);
} elsif ($mode eq 'server') {
run_server($port);
} else {
die "Invalid mode: $mode (use 'server' or 'client')\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment