【问题标题】:Perl Socket File Transfer ProblemsPerl 套接字文件传输问题
【发布时间】:2014-06-11 03:09:25
【问题描述】:

我的连接正常,数据传输正常......在一定程度上。我正在设计一个设置客户端和服务器套接字的小程序。连接后,客户端可以向服务器发送文件。

我的问题是,当我开始发送我的“测试”文件时,服务器永远不会结束它的 while 循环。它不断将数据连接到输出文件中。更奇怪的是,输出文件中的数据是正确的,只是行之间有多余的空白。

我知道这是因为我没有使用 \n 字符,而是在服务器上添加了另一个 \n 字符。但是,如果我对客户大吃一惊,那么一切都在一条线上。因此,服务器(不管它是否添加换行符)在一行上全部输出,因为它只收到一行。如果我在服务器端咀嚼,我会得到一个空文本文件......这让我很困惑。

此外,服务器永远不会停止连接......即使在客户端断开连接后它也会产生无限循环。终端无限期地输出这个:

Use of uninitialized value $data in concatenation (.) or string at ./tcp_server.pl line 51, <GEN2> line 14.

这是我的服务器代码:

#!/usr/bin/perl

# Flushing to STDOUT after each write
$| = 1;

use warnings;
use strict;
use IO::Socket::INET;
use v5.10;

# Server side information
my $listen_port  = '7070';
my $protocal     = 'tcp';

# Finds IP address of host machine
# Connects to example site on HTTP
my $ip_finder = IO::Socket::INET->new(
   PeerAddr=> "www.google.com",
   PeerPort=> 80,
   Proto   => "tcp"
) or die "The IP can not be resolved: $!\n";

# The found IP address of Host
my $ip_address = $ip_finder->sockhost;

# Creating socket for server
my $server = IO::Socket::INET->new (
    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 IP: $ip_address\n";
print    "Waiting for client connection on port $listen_port\n";

# Accept connection
my $client_socket = $server->accept();

open(my $fh, ">out")
    or die "File can not be opened: $!";
while($client_socket) {

    # Retrieve client information
    my $client_address = $client_socket->peerhost();
    my $client_port    = $client_socket->peerport();
    print "Client accepted: $client_address, $client_port\n";

    my $data = <$client_socket>;
    print $fh "$data\n";

}
close $fh;
$server->close();

和客户:

#!/usr/bin/perl

# Flushing to STDOUT after each write
$| = 1;

use warnings;
use strict;
use IO::Socket::INET;
use v5.10;

# Client side information
# Works by setting $dest to server address, needs to be on same domain
# my $dest      = '<IP goes here>';
# my $dest      = '<IP goes here>';
my $dest        = '<host>.cselabs.umn.edu';
my $port        = '7070';
my $protocal    = 'tcp';

my $client = IO::Socket::INET->new (
    PeerHost    =>  $dest,
    PeerPort    =>  $port,
    Proto       =>  $protocol,
) or die "Socket could not be created, failed with error: $!\n"; # Prints error code

print "TCP connection established!\n";

open(my $fh, "<test")
    or die "Can't open: $!";
while(my $line = <$fh>) {
    print $client $line;
}
close $fh;
# sleep(10);
$client->close();

【问题讨论】:

  • 透露您正在使用的机器的 IP 地址不是一个好主意,特别是在开发完全不关心安全性的协议时!
  • 我明白了,这有点不同。这个范围非常小。这是一个家庭作业,我只是遇到了一点麻烦。通过显示 IP,我可以将其输入到我的客户端。当我在不同的主机上运行它时,这很好。它只是让我的事情变得更容易。我完全理解这种担忧!
  • 我的意思是任何阅读这个帖子的人都可以访问你的服务器并滥用它的错误来控制机器。
  • 我明白,但在这种情况下并不重要。无法通过外线访问服务器(除非已使用 VPN,即使那样您仍然需要跳过更多的环节)。更不用说这个线程中与服务器相关的所有这些信息都是公共信息,你可以在他们的网站上找到这些服务器名称。如果您想了解有关服务器安全详细信息的更多信息,可以发送电子邮件至 operator@cselabs.umn.edu。

标签: perl sockets tcp file-transfer


【解决方案1】:

您不会在客户端添加换行符。客户端只是从文件中读取一行(包括换行符)并将其打印到套接字,但不添加另一个换行符。但是在服务器上,您从套接字读取该行(包括换行符)并添加另一个换行符。此外,服务器中的循环条件不正确。您不应该检查套接字是否存在,因为即使在连接关闭后它也会存在。相反,您应该在阅读时检查错误(这是您未定义的警告的来源)。而且,最好不要逐行读取,而是独立于行读取块,例如

while (read($client_socket, my $data, 8192)) {
    print $fh $data;
}

【讨论】:

  • 我会记住的!我可能会在我的 UDP 版本中实现这个答案。我想通了,不再使用相同的 while 循环进行文件传输。它们仍然相似并且可能会更好......但我设法来回发送一些图片文件并且它正在工作。谢谢!
猜你喜欢
  • 2016-10-28
  • 2011-08-11
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 2015-03-06
  • 2015-05-16
相关资源
最近更新 更多