Question

Afternoon,

I am writing a small UDP Client/Server in Perl and am having some issues sending files. I understand I need to break the file into chunks (datagrams) and send them to the server.

I am stuck figuring out how to break the file up into datagrams and send them. As of now, I can establish a UDP connection just fine, the server reports when it is received a UDP packet. This is what I have so far, any help would be greatly appreciated!

Server:

#!/usr/bin/perl

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

use warnings;
use strict;
use IO::Socket;

# Server side information
my $listen_port     = 7070;
my $protocal        = 'udp';
my $received_data   = undef;

# Creating UDP socket for server
my $server = IO::Socket::INET->new (
    LocalPort   => $listen_port,
    Proto       => $protocal,
    Type        => SOCK_DGRAM
) or die "Socket could not be created, failed with error $!\n";

print "Waiting for client connection on port $listen_port\n";

open(FILE, ">output.UDP")
  or die "File can not be opened: $!";

while($server->recv($received_data, 1024)) {
    my $peer_address = $server->peerhost();
    my $peer_port    = $server->peerport();
    print "Message was received from: $peer_address, $peer_port\n";
    print FILE "$received_data";
}
close FILE;

print "Closing socket...\n";
$server->close();

Client:

#!/usr/bin/perl

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

use warnings;
use strict;
use IO::Socket;

# Client side information
my $host        = 'apollo.cselabs.umn.edu';
my $port        = 7070;
my $protocal    = 'udp';
my $datagram    = undef;

# Creating UDP socket for client
my $client = IO::Socket::INET->new (
    PeerAddr    => $host,
    PeerPort    => $port,
    Proto       => $protocal,
    Type        => SOCK_DGRAM
) or die "Socket could not be created, failed with error: $!\n";

# Open and specified file
open(FILE, "10MBfile.dat")
    or die "Fine can not be opened: $!";
$client->send("test");

# Send file line by line
while (<FILE>) {
    $datagram = $_;
    $client->send("$datagram");
}
close FILE;
# sleep(10);
$client->close();
Était-ce utile?

La solution

Your code is already breaking up the file into chunks. By calling <FILE> each chunk will be one line. But there are several problems:

  • If the line gets too long and will not fit into a packet it cannot be transferred
  • UDP does not guarantee the delivery, so you receiver might miss data or might even duplicate data
  • UDP does not guarantee the order of delivery, so your receiver might get later data first

These drawbacks are probably not acceptable with file transfer, so you need to add layers on top of UDP to work around them, e.g. sequence numbers to detect duplicates and reordering and acknowledgments to trigger resubmissions on lost data. Or you could simply use TCP instead which has all these and more built in already.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top