Receive UDP packet datagrams in PHP

14,274

I've not done this with PHP before, but my first guess would be that you are getting a binary string back, which you'll need to convert into ASCII (or whatever character set you're using).

It looks like you should be able to use PHP's unpack for this.

It's hard to know exactly what format to provide pack without knowing what data you're getting back. It looks like unpack would at least be able to give back an array of decimal values (assuming you're getting characters back), which you could then convert into ASCII, with chr. It might be something like this:

//Receive some data
$r = socket_recvfrom($sock, $buf, 512, 0, $remote_ip, $remote_port);
//Convert to array of decimal values
$array = unpack("c*chars", $buf);
//Convert decimal values to ASCII characters:
$chr_array = array();
for ($i = 0; $i < count($array); $i++)
{
    $chr_array[] = chr($array[$i]);
}

It depends on the protocol design as to how complex your parsing of the binary data needs to be (That is, are you just sending string data, or a mix of integers and strings, etc... You need to parse the binary data accordingly).

EDIT: I've updated the format string to match an indefinite number of characters, using the array element name 'chars' as per the format listed here.

EDIT: Added some elementary ASCII conversion to code example.

Share:
14,274
dslauter
Author by

dslauter

Updated on June 12, 2022

Comments

  • dslauter
    dslauter almost 2 years

    I am working in php to build a listening server for a GPS tracking system. The GPS sends data through UDP packets, which I can display by running the below script. However the actual data comes out in symbols so I am guessing I am missing a conversion

        //Reduce errors
        error_reporting(~E_WARNING);
    
        //Create a UDP socket
        if(!($sock = socket_create(AF_INET, SOCK_DGRAM, 0)))
        {
            $errorcode = socket_last_error();
            $errormsg = socket_strerror($errorcode);
    
            die("Couldn't create socket: [$errorcode] $errormsg \n");
        }
    
        echo "Socket created \n";
    
        // Bind the source address
        if( !socket_bind($sock, "192.168.1.29" , 1731) )
        {
            $errorcode = socket_last_error();
            $errormsg = socket_strerror($errorcode);
    
            die("Could not bind socket : [$errorcode] $errormsg \n");
        }
    
        echo "Socket bind OK \n";
    
        //Do some communication, this loop can handle multiple clients
        while(1)
        {
            echo "\n Waiting for data ... \n";
    
            //Receive some data
            $r = socket_recvfrom($sock, $buf, 512, 0, $remote_ip, $remote_port);
            echo "$remote_ip : $remote_port -- " . $buf;
    
                //Send back the data to the client
            //socket_sendto($sock, "OK " . $buf , 100 , 0 , $remote_ip , $remote_port);
    
        }
    
        socket_close($sock);
    
  • dslauter
    dslauter over 10 years
    Thank you, it looks like it is coming in Binary. This is now the output. A¤¡ÿ}©x
  • dslauter
    dslauter over 10 years
    Actually I have to go to hexadecimal from Binary. I will go through the unpack man page. thank you very much
  • Geekman
    Geekman over 10 years
    @dslauter Can't see where you've listed the output? Do you have a technical specification of the GPS data? Eg. What are all the headers, what values do they have (are they unsigned integers, longs etc...). Some kind of spec for the protocol is what you're going to have to work off of to know how to properly parse the binary.
  • Geekman
    Geekman over 10 years
    @dslauter No problem. I think if you're converting to HEX, you can use bin2hex()? Don't quote me on that function name, though.
  • Geekman
    Geekman over 10 years
    @dslauter Might be worth reading this page too, the comments section has some useful examples for various applications of hex conversion: php.net/function.bin2hex