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

I've made a server application for a project. It's working ok on the input side - it reads the client input no problem. The client input is not in perl - it is sending data, and then terminating the data with a zero byte. When I try to send the server response back to the client by using

{ # the beginning of the event loop is above ... local $\ = "\0"; print $socket $data; # $socket is a IO::Socket::INET object return; }
it does not work - the client seems to acknowlege the zero char, but not the data that comes before. So I have 2 questions.

1. How would I send a stream of characters through the filehandle to the client? I'm thinking that that may be the answer.

2. What other ways can you write a zero byte beside "\0"?
_______________________________________________
"Intelligence is a tool used achieve goals, however goals are not always chosen wisely..."

Replies are listed 'Best First'.
Re: more zero byte madness
by Fastolfe (Vicar) on Dec 05, 2000 at 18:40 UTC
    I don't mean to ask a stupid question, but your code above is consistent with the output you're wanting. $data should be sent to the client followed by a null byte. My question is this: Are you certain $data has the value you expect? Are you certain that the client is getting an empty message (a single null byte)?
      Well, in a word, yes. Here's what I've done to verify the output.

      I've stepped through the code using the debugger and seen the actual output string.generated.

      I've telneted into the server, typed in an appropriate request and recieved from the server the appropriate response as well.
      _______________________________________________
      "Intelligence is a tool used achieve goals, however goals are not always chosen wisely..."

        Perhaps there is a buffering issue here? What you're describing isn't quite consistent with that, so if that's the case, something isn't quite as you say it is.

        If you want to be doubly certain it's not your client and it's not your network, use something like ngrep to verify the contents of the message. Verify that the entire command is in the message and that it is terminated with a null byte. I cannot imagine that this is not the case.

        On the server side, be sure you aren't doing something like while (<$client>) { ... } (without setting $/). Since you're dealing with a binary protocol, it's better in my experience that you use something like sysread to read data, and subsequently chop that data up into discrete commands. You may also have success setting $/ to "\0" and try reading "lines" like above.

        If this is a buffering issue, though, I don't know why the server would see \0 but would not see the contents of the command. That just doesn't make any sense to me. With the information you've given us, I don't see how that is possible. Something isn't right.

Re: more zero byte madness
by snax (Hermit) on Dec 05, 2000 at 23:59 UTC
    A quick question:
    Is $socket really an IO::Socket::INET object or is it the result of the accept method?

    I did a simple test script:

    #!/usr/local/bin/perl -w use strict; use IO::Socket; my $sock = IO::Socket::INET->new( Proto => 'tcp', LocalPort => 8080, Listen => SOMAXCONN, Reuse => 1 ); my $data = 'Silly test string.'; { local $\ = qq(\0); print $sock $data || die "What happened? $!"; }
    ..and this executes just fine, no warnings, no errors. Did I mention that there's no client on the other end?

    If you don't make $socket like this (set your ports and such however):

    $inet = IO::Socket::INET->new( Proto => 'tcp', LocalPort => 8080, Listen => SOMAXCONN, Reuse => 1 ); $socket = $inet->accept();
    then it's entirely possible that you never talk to your client properly at all. The fact that it exits as though it sees a null byte may simply be a timeout exit.

    Just a thought -- I'm no socket guru :)