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

I am making some changes to old code this week, and I am getting annoyed with my method of socket communications... The old (working) code sent a series of values as a %-delimited string, which is then split on the receiving end into an array. Ugly!

So, I decided to rewrite it quickly to send and receive an array, and do away with the ugly %-delimited string. But it's not working. No errors on either end, but it hangs up the system. A half dozen Google searches later, and I've come to the conclusion that what I'm trying to do is not possible, and that %-delimited string is there for a good reason.

Does anybody here have insight into this? Is my assessment correct? Is there a better way than what currently works?

Replies are listed 'Best First'.
Re: Send/receive array through IO::Socket?
by isotope (Deacon) on Dec 01, 2005 at 20:38 UTC
    Your big picture problem is that you need to serialize your data before passing it along -- sockets know only a series of bits, not data structures. As suggested before, YAML is an excellent choice for most uses. Perhaps the more traditional method is Storable, but there are plenty of choices available.


    --isotope
      sockets know only a series of bits, not data structures.

      Okay. That validates my conclusion. Thanks! Unfortunately, Storable suffers the same inconvenience as YAML. At least I'm on the right track now.

        Not quite. Storable suffers completely different inconveniences from YAML. Storable can get tripped up if the levels of Storable on client and server aren't compatable. You have to be a bit careful if the endianness of the client and server are different (I think there's an "nstore" and "nthaw" for network-order storing) - assuming the levels of Storable are otherwise compatable.

        But it is part of the core, so it's already installed. That inconvenience is unique to YAML. (Well, unique in the context of YAML vs Storable.)

        Storable has been a standard module for quite a while.

        Phil

Re: Send/receive array through IO::Socket?
by philcrow (Priest) on Dec 01, 2005 at 20:31 UTC
    Sounds like you need YAML.

    Phil

      I forgot to mention that this is on a server I don't own, and getting modules installed is possible, but very difficult... So much so that I'd rather remain ugly than go through the process of getting another module. :-)

        YAML is Pure Perl, so you don't need any special permissions or tools to install it. But if you still want an alternative, I once wrote a simple but efficient serializer/deserializer. You'll need to add something to know when you've reached the end of the structure.
Re: Send/receive array through IO::Socket?
by jeffa (Bishop) on Dec 01, 2005 at 21:16 UTC

    If you know, 100%, that the % sign will never appear in your data, then what you already have should be enough, shouldn't it? But yes, there are better ways to serialize your data, and YAML and Storable are two ways that work. A naive and straight-forward solution would be to use Data::Dumper and eval:

    sub encode { return Dumper [@_]; } sub decode { my $VAR1; my $string = shift; return eval "$string"; }
    I have not fully tested this method out, and though it does work for most complex data structures that involve arrays, hashes, and references to those, i coded this to only handle arrays.

    I recommend using more robust ways of serializing your data, such as Storable, YAML, or even XML. But i did feel inclined to post this code, at the very least to see if anyone can see ways to break this code. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      decode("system('rm -rf /home/jeffa')");
      Be careful with using eval() unless you're absolutely sure the string you're evalling is trustworthy. For data recieved from a network socket that level of trust is pretty hard to come by!

      -sam

Re: Send/receive array through IO::Socket?
by zentara (Cardinal) on Dec 02, 2005 at 10:50 UTC
    EasyTCP has built-in serialization using Storable, you might want to look at how he does it. It passes hashes too, which is quite handy.

    An example of Storable use can be found in Client/Server Messaging


    I'm not really a human, but I play one on earth. flash japh
        If you need some client-server examples for Easy::TCP, let me know.

        I'm not really a human, but I play one on earth. flash japh