I am writing a small program for a networking class I have and ran into a little confusion.
I have things working currently but am seeing some inconsistencies among perl networking examples I find.
Some people import the Socket module, while some import the IO::Socket module. Even more confusing, some import both Socket and IO::Socket.
Is there a point? I thought IO::Socket would import Socket?
I ask because I am trying to use a function "getaddrinfo()" and it keeps yelling at my about "Undefined subroutine &main::getaddrinfo called at ./tcp_server.pl line 13." Which is in the Socket perldoc.
I got it working by manually specifying the host IP... but I want it to automatically retrieve the host IP of the machine it is running on. Any advice?
Here is my code:
#!/usr/bin/perl
# Flushing to STDOUT after each write
$| = 1;
use warnings;
use strict;
use Socket;
use IO::Socket::INET;
# Server side information
# Works with IPv4 addresses on the same domain
my ($err, @res) = getaddrinfo(`hostname`); #'128.101.38.191';
my $listen_port = '7070';
my $protocal = 'tcp';
my ($socket, $client_socket);
my ($client_address, $client_port);
# Data initializer
my $data = undef;
# Creating interface
$socket = IO::Socket::INET->new (
LocalHost => shift @res,
LocalPort => $listen_port,
Proto => $protocal,
Listen => 5,
Reuse => 1,
) or die "Socket could not be created, failed with error: $!\n"; # Prints error code
print "Socket created using host: @res \n";
print "Waiting for client connection on port $listen_port\n";
while(1) {
# Infinite loop to accept a new connection
$client_socket = $socket->accept()
or die "accept error code: $!\n";
# Retrieve client information
$client_address = $client_socket->peerhost();
$client_port = $client_socket->peerport();
print "Client accepted: $client_address, $client_port\n";
# Write
$data = "Data from Server";
print $client_socket "$data\n";
# Read
$data = <$client_socket>;
print "Received from client: $data\n";
}
$socket->close();
It's much easier to only use IO::Socket:
use strict;
use warnings;
use IO::Socket::INET;
my $server = IO::Socket::INET->new(
LocalPort => 7080,
Listen => 10,
Reuse => 1
) or die $!;
while (1) {
my $client = $server->accept or next;
print $client "foo\n";
}
And if you want to do IPv6 just replace IO::Socket::INET with IO::Socket::IP or IO::Socket::INET6. And if you later want to use SSL on the socket replace it with IO::Socket::SSL and add some certificates. It's a bit overhead but a lot less writing of code and much easier to understand.