我正在为一个网络课程编写一个小程序,并且遇到了一些困惑。
我目前有些工作,但我发现在我发现的perl网络示例中存在一些不一致。
有些人导入Socket模块,而有些人导入IO :: Socket模块。更令人困惑的是,有些导入了Socket和IO :: Socket。
有没有意义?我以为IO :: Socket会导入Socket?
我问,因为我正在尝试使用一个函数“getaddrinfo()”,它一直在大吼大叫我的“未定义的子程序& main :: getaddrinfo在./tcp_server.pl第13行调用”。这是在Socket perldoc。
我通过手动指定主机IP来实现它...但我希望它能够自动检索运行它的机器的主机IP。有什么建议吗?
这是我的代码:
#!/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();
答案 0 :(得分:4)
仅使用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";
}
如果你想做IPv6,只需用IO :: Socket :: IP或IO :: Socket :: INET6替换IO :: Socket :: INET。如果您以后想在套接字上使用SSL,请将其替换为IO :: Socket :: SSL并添加一些证书。这有点开销,但编写代码的次数要少得多,而且更容易理解。
答案 1 :(得分:3)
您需要从Socket导入getaddrinfo()
。请参阅the docs。
use Socket 'getaddrinfo';
您可能希望在Linux系统上使用Sys::Hostname而不是`hostname`
。无需为此付出代价。