IO :: Socket vs Socket做我"使用"都?

时间:2014-03-03 15:13:38

标签: perl sockets tcp hostname name-resolution

我正在为一个网络课程编写一个小程序,并且遇到了一些困惑。

我目前有些工作,但我发现在我发现的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();

2 个答案:

答案 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`。无需为此付出代价。