Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: No data received on client socket

by caelifer (Scribe)
on Sep 19, 2006 at 19:51 UTC ( [id://573804]=note: print w/replies, xml ) Need Help??


in reply to No data received on client socket

Just a wild guess here. I notice that your code is executed within eval block. However, you do not check for its status, which means that you silence any errors and/or exceptions. Try to check for $@ in your last statement.

Also, depending on the socket option, i.e. if your socket is nonblocking, you should check for EAGAIN system error to see if the socket is ready to be read. Better yet use select or its OO counterpart IO::Select to determine if socket is readable.

Update: Fixed mixup between $! and $@, pointed out by ikegami

use IO::Select; my $sock_read_hdl = IO::Select->new(); $sock_read_hdl->add($oSocket); # Block here until message arrives my ($read_ready) = IO::Select->select($sock_read_hdl, undef, undef, un +def); # Now we are ready to read message. Note: $read_ready->[0] == $oSocket + here. eval { ... } or die $@; # As pointed out by ikegami, thanks.

I usually use a function instead of eval block and return an array containing message, byte count and possible error. Such as in

sub read_msg { my ($sock, $bcount, $buf, $msg) = (shift, 0, '', ''); # Use sysread for stream-oriented sockets READ_MSG: while (my $bytes_read = sysread($sock, $buf, 1024)) { # Handle partial read $bcount += $bytes_read; $msg .= $buf; } # Just in case redo READ_MSG if $! =~ /Resource temporarily unavailable/; # All other errors trigger unconditional return with error return ($msg, $bcount, $!) if ($!); # Return success return ($msg, $bcount, ''); }

So now our message reading routine looks like ...

... # Instead of eval block use our new function call my ($msg, $bcount, $error) = read_msg($read_ready->[0]); # Check for errors and empty messages die $error, "\n" if ($error); die "Nothing received!\n" if ($bcount == 0); ...

Hope this helps with your problem here. BR

Replies are listed 'Best First'.
Re^2: No data received on client socket
by ikegami (Patriarch) on Sep 19, 2006 at 20:54 UTC

    eval sets $@ when it catches an exception, yet you check $! in the first snippet.

    In the second snippet, you're relying on $! being false when there has been no error, but $!'s value is undefined (which is not to say that $! is undef) in that circumstance.

      I fixed the $! and $@ mixup as per your suggestion, duh :) . However, I'm not following your point regarding $! in the second snippet. Undefined value should always produce false condition on which I rely in my checks. Could you eleborate more?

        When the value of a variable is undefined (as opposed to the variable being undefined), it means there's no way to predict what value the variable has.

        In context, it means that $! could be true even no error occured. $! is only meaningful if sysread returned undef.

Re^2: No data received on client socket
by rbi (Monk) on Sep 19, 2006 at 20:27 UTC
    I did try to use your suggested code, but it never gets after:
    # Block here until message arrives my ($read_ready) = IO::Select->select($sock_read_hdl, undef, undef, un +def);
    This is in line with the behavior of the original code, where the message string is empty, but now I know that no message arrives. Even if I can see with tcpdump that the message arrives on the network card of the Linux client.
    Thank you very much in any case.
      This looks more and more like a network / os configuration problem. Check your host configs. Is there a pocket filter active on the host itself? Is it possible that you have some other client binded to the same port? I'm not sure if socket interface on Windows allows that though. As a last suggestion try write a simple echo server and run it on the localhost with the same port number and see if your application can receive a message. Or maybe simulate a network exchage with Telnet session.

      BR

      # Simple echo server using POE framework (from CPAN) #!/usr/bin/perl use warnings; use strict; use POE qw(Component::Server::TCP); POE::Component::Server::TCP->new( Port => 12345, ClientInput => \&client_input, ); POE::Kernel->run(); exit; sub client_input { my ($heap, $input) = @_[ HEAP, ARG0 ]; print "[$$]: $input\n"; $heap->{client}->put($input); }
        I tried to run the echo server but I don't get anything back.
        This is the tcpdump kind of output I get out of the original script (and with yours and ikegami's suggestions):
        client:/home/user # tcpdump -i eth0 -A port 6928 -xX -vv -s 0 listening on eth0, link-type EN10MB (Ethernet), capture size 65535 byt +es 16:59:48.813909 IP (tos 0x0, ttl 64, id 22143, offset 0, flags [DF], +proto: TCP (6), length: 60) client.12110 > server.6928: 16:59:48.814003 IP (tos 0x0, ttl 128, id 58743, offset 0, flags [DF], +proto: TCP (6), length: 64) server.6928 > client.12110: S, cksum 0x82 +75 (correct), 1326247112:1326247112(0) ack 4102086732 win 17520
        I've noticed that the port on the client changes every time i run the script. May it be this the problem ? How could I stick it to the 6928 port ?
        Unfortunetely I cannot run right now tcpdump on the older Linux boxes where it works fine, to see if there is any difference.
        Thanks a lot for any hint.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://573804]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (4)
As of 2024-04-25 16:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found