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

Hello. I'm having trouble with perl sockets. I want to 'use Socket' and not IO::Socket, but whatever I did won't produce the correct output. Here is what I'm feeding to my server:

$ printf "\x05\x01\x00" | nc server port

Which doesn't produce any output on my server. Here's the code:
#!/usr/bin/perl use strict; use integer; use Socket; my $port = 50000; # Port to bind to my $FORK = 0; # Do we fork? my $proto = getprotobyname('tcp'); socket(SERVER, PF_INET, SOCK_STREAM, $proto) or die "socket:$!"; setsockopt(SERVER, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) or die "setsockopt: $!"; bind(SERVER, sockaddr_in($port, INADDR_ANY)) or die "bind: $!"; listen(SERVER, SOMAXCONN) or die "listen: $!"; if($FORK) { my $pid = fork(); die "fork: $!" if $pid < 0; exit if $pid; } for(;my $paddr=accept(CLIENT, SERVER); close CLIENT) { my ($ver,$nm,$methods) = (); recv(CLIENT,$ver,1,0); recv(CLIENT,$nm,1,0); if($ver == 0x05 && $nm) { print "Okay, getting $nm methods\n"; recv(CLIENT,$methods,$nm,0); } } exit;
What's wrong?

Replies are listed 'Best First'.
Re: Socket troubles
by serf (Chaplain) on Jan 22, 2006 at 19:35 UTC
    If you add use warnings; to the top of your code after use strict; you will find you get this error:
    Argument "^E" isn't numeric in integer eq (==) at ./try.pl line 40.
    When you do your connect. This could be a big clue for you :o)

    use warnings; is your friend!

    I think this should do what you want it to:

    if ( $ver =~ /\x05/ && $nm ) {
    or even:
    my $x05 = sprintf "\x05"; # hex 05 as a raw character for ver test. for ( ; my $paddr = accept( CLIENT, SERVER ); close CLIENT ) { my ( $ver, $nm, $methods ) = (); recv( CLIENT, $ver, 1, 0 ); recv( CLIENT, $nm, 1, 0 ); if ( $ver eq $x05 && $nm ) { print "Okay, getting $nm methods\n"; recv( CLIENT, $methods, $nm, 0 ); } }
    PS: your debugging could also be easier if you format your die statements more helpfully:
    socket( SERVER, PF_INET, SOCK_STREAM, $proto ) || die "Can't create socket: $!\n"; setsockopt( SERVER, SOL_SOCKET, SO_REUSEADDR, pack( "l", 1 ) ) || die "Can't set socket option: $!\n"; bind( SERVER, sockaddr_in( $port, INADDR_ANY ) ) || die "Can't bind to socket: $!\n"; listen( SERVER, SOMAXCONN ) || die "Can't set max connections (listen): $!\n";
      Why isn't 5 numeric? 5 is a number.

        Uhh, no x05 is not a number. It's a control character, ^E. If you want a number expressed, change the printf you are piping to netcat, e.g.,

        printf "510" | netcat 127.0.0.1 50000

        Scott