in reply to how to control segmented messages in TCP chat client

TCP is a stream-oriented protocol. Message boundaries are lost and fragmentation may occur at any time. It is useful to frame your data, ie establish a protocol layer on top of TCP.

A simple way to accomplish this is by prefixing your messages with their length: my $pkt = pack "n/a", $str; but line-based protocols are also common. Using readline could be tricky, though.

In any case, you'll want to buffer the stream. When a message is complete, rip it/them out of the buffer (unpack or split) and fire the message handler. Callback-driven logic will help you arrive at a clean, modular solution.

Replies are listed 'Best First'.
Re^2: how to control segmented messages in TCP chat client
by thanos1983 (Parson) on Aug 25, 2014 at 14:25 UTC

    Hello Anonymous Monk

    To be honest after so many different approaches, I came with another possible solution to yours but I do not know if many people will think it is a good option or not. I decided not to implemented due strict documentation prerequisites but I think it could work.

    In case that someone was facing a similar problem he could apply use bytes; and then no bytes;, official documentation bytes or length official documentation length. By doing so the user can get the size in bytes for the message that he wants to transmit, or the length of the message that he wants to transmit. Either way he can create a message containing the length to expect as a number or the size (Caution the user needs to subtract the size of the number after) and simple create a condition to collect all the messages together. Such as while ($msg_size != $msg) {}. This is of course a sample, but I think the idea after some experimentation can be applied.

    Seeking for Perl wisdom...on the process of learning...not there...yet!

      thanos1983,

        (Caution the user needs to subtract the size of the number after)

      You need to read the 4 byte size in order to know how many bytes to read. So don't subtract or you will lose the last 4 bytes of the message.

      Regards...Ed

      "Well done is better than well said." - Benjamin Franklin

        Hello flexvault,

        Thank you for your time and effort reading and replying to my question/commends. You are absolutely right about it, as I said this is a brief idea that needs experimentation to become generic and more solid.

        My assumption was build upon the user reads the length of the string (e.g. 40 characters) creates a string for transmission containing this number.

        For example $msg = $length . " " . $txt;. So when the receiver will get the message he knows that he needs to subtract the $length from the length($msg); in order to get the pure message which would be something like 40 character + 3 (length description with the space) = 43 characters. So if the user skips the first 3 characters of the message and reads the rest 40 can know that he got the whole message. Even in case the message was segmented.

        Well this is only a brief idea that I was planning to implement.

        Sample of code of my idea by using substr including the output:

        #!/usr/bin/perl use strict; use warnings; my $msg = "This is just a sample of message."; my $length = length($msg); my $number = length($length); print "\$number: ".$number."\n"; my $transmit = $length . " " . $msg; print "\$transmit: ".$transmit."\n"; my $receive = substr $transmit, 3; print "\$receive: ".$receive."\n"; __END__ $number: 2 $transmit: 33 This is just a sample of message. $receive: This is just a sample of message.

        The solution as it is right now, can not be generic, because the receiver needs to know how many digits need to subtract from the $msg. In case that someone wants to make a generic solution, I would recommend the user to read the string and get the actual length before subtracting. As I said, it needs some small experimentation to become generic and more solid solution, but I think it is possible as an idea to be implemented.

        Again thank you for your time and effort reading and replying to my query.

        Seeking for Perl wisdom...on the process of learning...not there...yet!