in reply to How to end socket file transfer without closing socket

You need to expand you protocol. Here are some ideas based on existing protocols:

HTTP

The size of the body ("Content-Length") is transmitted before the body itself, so the receiver knows when to stop listening for the body and start listening for another request or response.

Pro: Trivial to implement.
Con: Sender needs to know data's length in advance.
Con: Fails poorly when an error occurs.

FTP

A command connecion is maintained. Commands are exchanged to create new connections over which data is transfered.

Pro: Handles errors easily.
Con: More complex to implement.
Con: Harder for firewalls and proxies to handle.

SLIP

Packets are terminated with a special character ("\0300") that is not allowed to exist anywhere else in the stream. An encoding mechanism is provided to transmit these special characters as data ("\0300" is encoded as "\0333\0334" and "\0333" is encoded as "\0333\0335").

Pro: Easy to implement.
Pro: Sender doesn't need to know data's length in advance.
Pro: Can handle errors without breaking the connection.

Update: Added pros and cons.

  • Comment on Re: How to end socket file transfer without closing socket

Replies are listed 'Best First'.
Re^2: How to end socket file transfer without closing socket (MIME)
by tye (Sage) on Oct 23, 2007 at 17:18 UTC

    I kinda like MIME's choice. XML's CDATA seems rather pointless to me, by contrast (having such a strange syntax that still requires one to escape a 3-char delimiter but whose existance is "justified" because you don't have to escape a 1-char delimiter).

    For MIME, you pick some short, random string (from a restricted set of characters). If that string is in the data to be sent, then look at the character that follows it and append some other random character on the end of your random string. Repeat until you have a string that does not appear anywhere in your data. Then output the delimiter before and after the data. It requires that you scan the data to be sent once before you send it but is robust in the face of character translations in your pipe (important in an e-mail protocol where trailing spaces might not be preserved, for example) and doesn't require any transformation of the data to be sent.

    - tye        

Re^2: How to end socket file transfer without closing socket
by redss (Monk) on Oct 23, 2007 at 17:13 UTC
    Thanks for the ideas. If the receiver knows the filesize, how can the following snippet be modified to not read and write more than the filesize?
    while (<$sock>) { print INPUT $_; }
      my $sock_in = ...; my $fh_out = ...; my $bytes_to_read = ...; while ($bytes_to_read > 0) { my $bytes_read = read($sock_in, my $block = '', $bytes_to_read); if (!$bytes_read) { my $msg = defined($bytes_read) ? 'Socket closed unexpectedly' : +$!; die("Unable to read from sender: $msg\n"); } $bytes_to_read -= $bytes_read; print $fh_out $block; }

      Update: It was an infinite loop. Fixed.

      I've repeatedly noted that <$sock> is generally a pretty bad idea. Lots of problems get traced back to that. See read, sysread, and recv for alternatives.

      - tye        

        Could you explain how <$sock> is a pretyy bad idea? Some script I wrote in this mechanism seems work well by far.
        If it's really exist some inevitable bug or flaw, I have to modify to fix.
        Thanks!


        I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction