If anyone's interested, after much searching through the manual and playing around, I figured it out!
Because it's udp and as such a connectionless protocol, it doesn't actually create the virtual circuit until some data is sent. BUT you can't test to see whether it actually sent the data, because it doesn't send back an acknowledgement of receipt like tcp does, as such, your fwrite to the socket will always work, even if there is no connection, so you have to do your error-checking on your first fread. You also have to set your socket timeout, because otherwise you'll be waiting for ages for the fread to timeout when it doesn't recieve a response. What an evil thing 😉
Anyway, here's the fixed (sort of!) prototype code:
<?php
// quake 3 connection
// Set the host and port
$host = "202.12.147.60";
$port = 27960;
// Open the socket connection to the server
$fp = fsockopen("udp://".$host, $port);
// Set the string to send to the server
$string = "\xff\xff\xff\xffgetinfo";
// Set the socket timeout to 2 seconds
socket_set_timeout($fp, 2);
// Actually send the string
fwrite($fp, $string);
// Read the first 18 bytes to get rid of the header and do the error checking here
if(!fread($fp, 18)) {
die("Oh God, the pain!");
}
// Get the status of the socket, to be used for the length left
$status = socket_get_status($fp);
// Read the rest
$info = fread($fp, $status['unread_bytes']);
// Explode the result of the fread into another variable
$array = explode("\\", $info);
// Loop through and create a result array, with the key being even, the result, odd
for($i = 0; $i < count($array)/2; $i++) {
$result[$array[$i*2]] = $array[$i*2+1];
}
// Print the result for error checking
print_r($result);
// Close the file pointer
fclose($fp);
?>
as simple as that!