http://www.perlmonks.org?node_id=5990

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question: (network programming)

How do I send a file through a Socket Connection ?

Originally posted as a Categorized Question.

  • Comment on How do I send a file through a Socket Connection ?

Replies are listed 'Best First'.
Re: How do I send a file through a Socket Connection ?
by btrott (Parson) on Mar 24, 2000 at 04:13 UTC
    The client shouldn't be calling accept, should it? The server should, in order to accept new clients.

    Here's a really simplistic example of sending a file across a socket. Here's the server:

    use IO::Socket; my $server = IO::Socket::INET->new( Listen => 5, LocalAddr => 'localhost', LocalPort => 5050, Proto => 'tcp' ) or die "Can't create server socket: $!"; my $client = $server->accept; open FILE, ">out" or die "Can't open: $!"; while (<$client>) { print FILE $_; } close FILE;
    And here's the client:
    use IO::Socket; my $server = IO::Socket::INET->new( PeerAddr => 'localhost', PeerPort => 5050, Proto => 'tcp' ) or die "Can't create client socket: $!"; open FILE, "in"; while (<FILE>) { print $server $_; } close FILE;
    This should get you started. Just start up the server in the background, then run the client, and it should send the contents of "in" to "out", over the socket.

    You'll probably want to tinker around with it a bit--perhaps put in some command line options for the host and port; make it so that the server handles multiple connections (using IO::Select); etc.

      You're right, I'm really lame today. Plus, I can't seem to edit my existing nodes for some reason. Maybe vroom should take the bit about filehandles out of my answer and the code out of yours and call it good on this one. :)
      In the Client and the server respectively-if they exist on different hosts, then what are the values of 'localhost' for each? Also, I can't see where the client code actually makes contact with the server? Would really appreciate a fairly rapid answer. Thanks in advance.
      I've used snippets of this code for a speedy little internal file server for a while (albeit the reverse direction of the example). We just installed a fresh RedHat 8.0/perl5.8.0/dual athlon box, and for some reason, the client always corrupts the file. The file is always 50% larger than the original. It also seems the garbage appears in the same offsets in the file, but the garbage is different each time. Any idea why such simple code broke? joel@acdstar.com
Re: How do I send a file through a Socket Connection ?
by chromatic (Archbishop) on Mar 24, 2000 at 01:42 UTC
    The IO::Socket package inherits from IO::Handle, so you can treat your socket (after it's all set up) like a filehandle. You can print to it or read from it! Just do something like:
    open(INPUT, $my_file) || die "Can't open: $!"; print $connection while (<INPUT); close(INPUT) || die "Can't close: $!";
    Disabling buffering ($| = 1) might be a good idea. You can also call select on the $connection object.

    On the server side, you can just read from the socket (once it is set up) with the normal angle operators. Using the accept() method will cause the server to listen to the socket until it gets a response, and it will return an object with filehandle properties. Whatever you want to do with it from there is up to you, once it's in a scalar or an array.

Re: How do I send a file through a Socket Connection ?
by SiMac (Initiate) on Apr 20, 2003 at 23:48 UTC
    Sometimes (mainly when you're passing a file from one a process running under one user id to another process under a different user id) it makes sense to pass the filehandle and not the file. To do this, you'd want to use Socket::PassAccessRights as follows:

    Socket::PassAccessRights::sendfd(fileno(SOCKET), fileno(FILE_DESCRIPTOR));

    On the other end you'd want to receive like:

    $file_descriptor = Socket::PassAccessRights::recvfd(fileno(SOCKET));

    This unlikely to work on any system not purporting POSIX compliance. According to the author of the module, the socket passing code in Linux and FreeBSD is buggy, so use this module only when necessary.