Created
July 3, 2025 06:38
-
-
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…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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