http://qs321.pair.com?node_id=602794


in reply to Sending a low-level query using sockets? (A confused newbie)

You need to receive packets like this:
$peeraddr = $sock->recv($packet, $maxpacketsize); # 2048 should work fine as maxpacketetsize
You'll have to look into the details of the protocol to tell how many packets to expect. Packets may arrive out of order. This is not necessarily a problem--it appears that in the Gamespy protocol the packets contain key-value pairs which can be interpreted in any order and that these are never split between packets (although there may be more than on pair per packet). If you don't receive all the packets you expect within a certain period of time, try sending the query again. Don't try too many times, though.

UDP is not a connection-oriented protocol, so this:

if(! defined $sock->connected)
doesn't actually tell you if you've connected. It just returns the (binary) IP address/socket port address that you used for PeerAddr. It will return this even if there is no host at the given IP address. There is also no way to tell if a send/syswrite/print actually succeeds--that is, if the data actually reached the remote host.

For example, this

use IO::Socket; $p = IO::Socket::INET->new(PeerAddr => "1.1.1.1:7170", Proto => "udp") or die "socket: $!\n"; if ($p->connected) { print "connect ok\n"} if ($p->write("foo")) { print "send ok\n"}
will print:
connect ok send ok
You might want to look at this C# library for ideas, although the Perl string methods are much simpler than the byte buffer methods he uses in C#.