【问题标题】:Passing name of file via socket in perl在perl中通过套接字传递文件名
【发布时间】:2021-02-27 06:53:37
【问题描述】:

我有 2 个用 perl 编写的脚本。第一个获取文件并通过套接字将其发送到服务器。服务器是我的第二个脚本 - 它保存到一个文件中。 服务器将文件保存为指定名称 - 在代码中已修复。如何在发送文件之前获取发送文件的名称,并将其发送到服务器? 我的代码如下: 客户:

my $socket = IO::Socket::INET->new(
    PeerAddr    =>  $local_host,
    PeerPort    =>  $local_port,
    Proto       => 'tcp',

)or die "Alert!";
my $bandwidth = 1024*5 ; # 5Kb/s - 
open my $fh, '<', "$direc/$my_data"
    or die "couldn't open the file";

  my $buffer ;
  while( sysread($fh, $buffer , $bandwidth) ) {
    print $socket $buffer ;
    sleep(1) ;
  }

  print "Data send.End \n" ;

  close ($fh) ;
  close($socket) ;

我的服务器:

my $my_socket = new IO::Socket::INET(
    LocalHost => $local_host,
    LocalPort => $local_port,
    Proto     => 'tcp',
    Listen    => 5,
    Reuse     => 1
);
die "Couldn't open my_socket $!n " unless $my_socket;
print "You can send the data now \n";
my $accepter = $my_socket->accept();
my $count=0;
#print "$directory.$save_dir/$my_data";
open my $fh, '>', "$direc/$save_dir/$my_data" #my data is the name, and it's "fixed", how to take it from client?
    or die "Couldn't open the file";
while(<$accepter>){
    chomp;
    last if $count++ ==10;
    say $fh $_;

}


print "End \n";
close $fh;
close $my_socket;

【问题讨论】:

    标签: perl sockets client-server


    【解决方案1】:

    让服务器写入客户端指定的文件名存在安全风险。客户端可以告诉服务器覆盖文件,包括服务器本身。

    改为使用 UUID 作为真实文件名。将客户端文件名/真实文件名对存储在别处。


    您需要提出一个协议,以便服务器可以区分文件名和内容。我们可以使用现有的格式,例如 JSON 或 YAML,但它们需要将整个文件放入内存并对内容进行编码。你可以编造一些东西,比如“第一行是文件名”,但我们可以做得更好。

    如果您想流式传输,我们可以使用精简的 HTTP 协议。将标题作为Key: Value 行发送。空行结束标头并开始发送内容。只需稍加努力,我们就有了一个可扩展的简单协议。

    这是使用UUID::Tinyautodie 的服务器主循环。

    # Read Key: Value headers until we see a blank line.
    my %headers;
    while(my $line = <$accepter>) {
        chomp $line;
        
        last if $line eq "";
    
        my($key, $value) = split /\s*:\s*/, $line;
        $headers{$key} = $value;
    }
    
    # Store the file in a random filename. Do not use the client's filename
    # to avoid a host of security issues.
    my $filename = create_uuid_as_string(UUID_V4);
    open my $fh, ">", "incoming/$filename";
    
    # Read the content and save it to the file.
    my $buf;
    while( read($accepter, $buf, 1024) ) {
        print $fh $buf;
    }
    
    say "$headers{Filename} was stored in incoming/$filename";
    close $my_socket;
    

    客户端在发送文件内容之前只是发送一个文件名头。

    open my $fh, '<', $filename;
    
    print $socket "Filename: $filename\n\n";
    
    my $buffer ;
    while( sysread($fh, $buffer , $bandwidth) ) {
        print $socket $buffer ;
    }
    

    【讨论】:

    • 好的,谢谢您的帮助。不幸的是,你的回答并没有解决我的问题。这是一个学校项目:(
    • @TheTrainer 抱歉,它没有解决什么问题?
    • 传递名称 ;) 我知道 - 这不安全。在您回答后,我想到了我的服务器。我以这种方式创建名称:“received_data_”。但我仍然无法发送文件名。
    • @TheTrainer 在答案中,客户端确实将文件名传递给服务器。它位于$headers{Filename}。它只是不使用它来打开文件,但您应该能够进行修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2016-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多