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

I found this module on the internet that deals with communicating over the internet and I'd like to mess with the code to change some things but I don't really understand the code which is based around the procedural form of Socket. So I my question is can anyone either translate this or just give me some translating tips as to how to go from Socket to IO::Socket?
sub q3msg { my ($host, $port, $timeout, $msg) = @_; my $iaddr = gethostbyname(hostname()); my $sin = sockaddr_in(0, $iaddr); socket(SOCK, PF_INET, SOCK_DGRAM, getprotobyname('udp')) or die "s +ocket: $!\n"; bind(SOCK, $sin) or die "bind: $!\n"; my $hisaddr = inet_aton($host) or die "unknown host \"$host\"\n"; my $srvaddr = sockaddr_in($port, $hisaddr); defined(send(SOCK, chr(255) x 4 . $msg, 0, $srvaddr)) or die "send +: $!\n"; my ($rin, $rout); $rin = ""; vec($rin, fileno(SOCK), 1) = 1; if (select($rout=$rin, undef, undef, $timeout)) { recv(SOCK, $_, 65507, 0) or die "recv: $!\n"; s/\033.//g; my @response = split /^/m; shift @response; return \@response; } else { return undef; } }


Update
To expand a little, the main change I was trying to do was try to avoid having to create a socket everytime, as currently when I use it its a tad slow (2-3 seconds to send/receive a response) and I was trying to optimize that, my first thought was to just create one socket that could stay in existance and hopefully make it a bit faster.

Replies are listed 'Best First'.
Re: Translating Socket to IO::Socket;
by pg (Canon) on Jan 08, 2004 at 02:27 UTC

    This kind of translation is usually very straight forward, I commented out some original code, and added mine immediately after.

    I didn't test the code, and guess you may have a peer to test against. There might be mistakes, but you can certainly come back and discuss.

    sub q3msg { my ($host, $port, $timeout, $msg) = @_; my $iaddr = gethostbyname(hostname()); my $sin = sockaddr_in(0, $iaddr); =document socket(SOCK, PF_INET, SOCK_DGRAM, getprotobyname('udp')) or die "s +ocket: $!\n"; bind(SOCK, $sin) or die "bind: $!\n"; =cut my $sock = new IO::Socket::INET(Proto => "udp", LocalAddr => $iadd +r, LocalPort => 0) or die "failed to create UDP socket"; my $hisaddr = inet_aton($host) or die "unknown host \"$host\"\n"; my $srvaddr = sockaddr_in($port, $hisaddr); #defined(send(SOCK, chr(255) x 4 . $msg, 0, $srvaddr)) or die "sen +d: $!\n"; defined(send($sock, chr(255) x 4 . $msg, 0, $srvaddr)) or die "sen +d: $!\n"; my ($rin, $rout); $rin = ""; vec($rin, fileno(SOCK), 1) = 1; if (select($rout=$rin, undef, undef, $timeout)) { #recv(SOCK, $_, 65507, 0) or die "recv: $!\n"; recv($sock, $_, 65507, 0) or die "recv: $!\n"; s/\033.//g; my @response = split /^/m; shift @response; return \@response; } else { return undef; } }

    Update:

    Actually you can take a look at those two nodes of mine: An internet garbage filter and My experience with Perl threading and the reason I think that I have rushed a little bit. The two pieces of code do the same thing, but the first one is threaded and uses raw socket, and the second one is not threaded and uses IO::Socket. By comparing those two pieces, you can get a good idea of the translation you wanted.

    By looking at the title of your post, I saw you compared IO::Socket with "Socket", instead of "socket". I guess (100% pure guess, my guess could be totally wrong) that, you might thought socket is defined in module Socket. That is not true. Raw socket is not defined as object. Module Socket does not give any socket implementation, indeed it just defines a bunch of helper methods, such as inet_atoi etc., also a set of socket related constants.

Re: Translating Socket to IO::Socket;
by perrin (Chancellor) on Jan 08, 2004 at 04:27 UTC
    One thing you should keep in mind is that the built-in socket stuff is significantly faster than IO::Socket. Switching to IO::Socket will slow things down for you, although it may simplify the code.
Re: Translating Socket to IO::Socket;
by pg (Canon) on Jan 08, 2004 at 04:48 UTC

    Read your update. If all what you want is to create socket once, and use it repeatedly, there is certainly no need for you to convert to IO::Socket. Just like you can use variables when you open files, you can do the same thing towards socket, and thus it follows the usual scope rules. For example: (code is tested)

    use Socket; use strict; use warnings; my $yahoo; socket($yahoo, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die "so +cket: $!"; connect($yahoo, sockaddr_in(80, inet_aton("www.yahoo.com"))) || die "c +onnect: $!"; syswrite($yahoo, "GET / HTTP/1.1\r\nHost: www.yahoo.com\r\n\r\n"); read_one_line($yahoo); read_one_line($yahoo); sub read_one_line { my $sock = shift; my $line = <$sock>; print $line; }

    This also works, but I like the first solution better:

    use Socket; use strict; use warnings; socket(YAHOO, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die "soc +ket: $!"; connect(YAHOO, sockaddr_in(80, inet_aton("www.yahoo.com"))) || die "co +nnect: $!"; syswrite(YAHOO, "GET / HTTP/1.1\r\nHost: www.yahoo.com\r\n\r\n"); read_one_line(*YAHOO); read_one_line(*YAHOO); sub read_one_line { my $sock = shift; my $line = <$sock>; print $line; }
Re: Translating Socket to IO::Socket;
by zentara (Cardinal) on Jan 08, 2004 at 17:50 UTC
    I found these well commented examples from the U of New Orleans very helpful in understanding Sockets. After reading thru these scripts, the IO::Socket perldoc is easier to understand. And it appears that IO::Socket, just uses Socket and makes the options more "understandable english". So Socket is IO::Socket without the overhead.

    Anyways look at the Perl section here-> UNO

    As a matter of fact, I recommend these scripts be placed into the tutorial section, with appropriate credit given.