Treehunter has asked for the wisdom of the Perl Monks concerning the following question:

I've been searching reciently for a tutorial on transferring a file over IO::Socket. I have attempted many random things, at this point the closest thing I have to working is Client:
#!/usr/bin/perl use strict; use IO::Socket; my $sock = new IO::Socket::INET( PeerAddr => 'localhost', PeerPort => 6224, Proto => 'tcp', ); open(FILE,">file.exe"); binmode(FILE); while(<$sock>) { print FILE <$sock>; } close(FILE); close($sock);
Server:
#!/usr/bin/perl use strict; use IO::Socket; my $sock = new IO::Socket::INET( LocalPort => 6224, Listen => 10, Proto => 'tcp', Reuse => 1, ); while(my $conn = $sock->accept()) { open(FILE,"macshift.exe"); binmode(FILE); print $conn <FILE>; close(FILE); }
At this point, both connect and seem to transfer the file, the file is the same size and everything. If you try to run the program you get an error saying couldn't load the program into memory so I assume something is going wrong with my use of binmode. Please enlighten me Perl monks ;-)

Replies are listed 'Best First'.
Re: Perl IO::Socket Transfer A File Help
by BrowserUk (Patriarch) on May 05, 2007 at 17:43 UTC
    ... an error saying couldn't load the program into memory ...

    I've never seen a perl error message like that? You'd be much better of quoting the actual text of the error, and identifying which of the programs you are running when you get that error, because then we stand a chance at understanding your problem.

    That said, the likely problem is that you are using too much memory.

    You are first loading the whole file into memory, and then transmitting the whole file effectively in one lump. At the other end, you are receiving the whole file as a single lump before writing it to disc.

    If the file is a large one, that is going to consume large amounts of memory, at least twice the on-disk size of the file and probably much more.

    You should seriously consider using read instead of the diamond operator, and read and write the file in small chunks at both ends.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Actually, I've been tinkering at this problem all morning while looking for tutorials that also might contain an example that would point out the problem, but something in my code is preventing the first two lines from being copied, which is why I'm getting this random memory error. Also the file transfered is just a random binary file and that gets a memory error after transfer, due to the fact that the first two lines where not being sent over the socket. I have managed to have it copy all but the first line and I cannot figure out why it skips the first line of the file when it copies it. Once I figure this out of course I think I will have solved my own problem. Code Update:
      #!/usr/bin/perl use strict; use IO::Socket; my $sock = new IO::Socket::INET( LocalPort => 6224, Listen => 10, Proto => 'tcp', Reuse => 1, ); while(my $conn = $sock->accept()) { open(FILE,"fucks.txt"); binmode(FILE); my @file = <FILE>; close(FILE); foreach my $x (@file) { print $conn $x; } }
Re: Perl IO::Socket Transfer A File Help
by Fletch (Bishop) on May 06, 2007 at 01:49 UTC

    Other problems with <$sock> aside, you're reading two "lines" at a time in your client (the first implicitly into $_ which you're discarding; the second "line" gets printed into your file; lather rinse repeat).

    You really want to read (or sysread) blocks and write (or syswrite) them out.