in reply to Sending & Receiving on a socket

I'm frustrated by how often I see people using <SOCK> to read from sockets. <SOCK> will hang until it finds either end-of-file or $/. You should use read, sysread, or recv to read from sockets (unless you have a somewhat unusual protocol that always sends end-of-line on the end of each packet, you know that $/ will match what the remote system is sending as end-of-line, and you don't care if your program hangs when something goes wrong with this).

Your $send_msg = scalar reverse $recv_msg; will move the "\n" to the front of the string which will make trying to read that data with <$sock> not ideal.

FYI, AFAICT sockets are always unbuffered.

        - tye (but my friends call me "Tye")

Replies are listed 'Best First'.
Re: (tye)Re: Sending & Receiving on a socket
by Rhandom (Curate) on Sep 13, 2001 at 20:48 UTC
    I'm sure I will be downvoted for disagreeing but...

    Using a newline (or CR LF pair) is not that unusual, and is actually rather common. SMTP and POP are two that come to mind and use nothing but CR LF for line endings. Also HTTP, FTP, and IMAP all use CR LF endings extensively (although they do have sections of data reading that is better left to sysread()).

    Doing a <SOCK> at the wrong time is a symptom of not knowing what you are dealing with while using sockets. It is more a problem of not being defensive than it is doing things wrong. Under most protocols (SOCK_DGRAM and recv() excluded) the programmer should make extensive use of alarm() to make sure he is timing out at apropriate waits. Even when doing a read() or sysread() the server or client could block if they have not read enough data to fulfill the protocol.

    Using a newline (or CR LF) is perfectly acceptible, if you know the protocol uses it, or have made up your own that uses it.

    However, when people don't know what they are doing, or aren't defensive, or don't know the protocol, tye is perfectly correct and doing a getline() should be avoided.

    my @a=qw(random brilliant braindead); print $a[rand(@a)];

      I said that it was fairly unusual to have a protocol that always sends end-of-line on the end of each packet. You managed to list only two. However, you have a very good point that text-only (or at least mostly text) protocols have become common (I'm more used to network protocols that don't assume all computers use ASCII -- but I'm just old). (:

      I wanted to state the case against <SOCK> a bit strongly because I've been seeing a lot of code using it when it shouldn't.

      Also note that using alarm() makes your code less portable. Having an alarm() actually trigger can leave Perl "confused". So that isn't a technique that I can highly recommend. Unfortunately, the alternatives are usually even more complicated and have their own faults so building very robust network servers in Perl gets messier than is often expected when programming Perl. ):

      Note that in the node that I was replying to, the author wrote both sides of the "protocol" and perhaps even meant to send "\n" on the end of each packet. Using read would have probably been enough for the person to figure out the mistake and would have been much simpler than trying to write a robust server and client that tries to handle lots of more unusual failure modes gracefully.

      Having something "hang" is one of the more difficult cases to debug and so I stand by my assertion that, in Perl, it is best to not use <> to read from sockets even when you expect that there will be a "\n" on the end of the next packet.

              - tye (but my friends call me "Tye")