CodeDezk
CodeDezk

Reputation: 1260

PHP send hex data to socket

I have to send some command to UDP socket server and get replay, below code works fine which is in c/c++ , and I am getting successful response from server using it.

typedef struct{
        unsigned char    type;            //type
        char             unsignedfunctionID;     
        unsigned short   reserved;     //Reserved
        int              unsignediDevSn;    // serial number 4-byte
        unsigned char    data [32];     // 32 bytes of data
        unsigned int     sequenceId;     // serial number
        unsigned char    extern_data [20]; 

}PacketShortAccess;

Sending to socket

PacketShortAccess statusCommand;
    statusCommand={0};
    statusCommand.type=0x19;          
    statusCommand.unsignedfunctionID=0x20;           
    statusCommand.reserved=0;     //Reserved
    statusCommand.unsignediDevSn=serialNumebr;   serial number 4-byte

    char sendData[sizeof(statusCommand)];
    memcpy(sendData, &statusCommand, sizeof(statusCommand));
    sendto(sockfd,sendData,sizeof(sendData),0,(struct sockaddr *)&servaddr,sizeof(servaddr));

Now I need to use the same command format in php,

I have tried like

//this the command format I am getting while printing on c++ code
$command="19 ffb0 0 0 ff88 d 38 19 ffd0 37 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ";
socket_sendto($sock, $command, strlen($command) , 0 , $server , $port)

But I am not getting any response from the server, I can I re-write above c++ code in php.

Upvotes: 0

Views: 596

Answers (1)

Jonathan
Jonathan

Reputation: 2877

PHP isn't as elegant as C++ when it comes to structs simply being that it's loosely typed. Things have improved with the introduction of PHP 7 & 7.1, but still not as strict as C++. Below is roughly the equivalent of the C++ struct.

The data you are sending doesn't seem to make sense, so you need to first understand what is type in c++ means, I won't expand on that but if you want you can see this off-site resource C++ Data Types

Struct

class PacketShortAccess {

    /** @var int */
    private $type;

    /** @var int */
    private $unsignedFunctionID;

    /** @var int */
    private $reserved = 0;

    /** @var int */
    private $unsignediDevSn;

    /** @var string */
    private $data;

    /** @var int */
    private $sequenceId;

    /** @var string */
    private $externData;

    /**
     * @return string
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * @param int $type
     *
     * @return PacketShortAccess
     * @throws Exception
     */
    public function setType($type)
    {
        if (
            false === is_int($type) ||
            $type < 0 ||
            $type > 255
        ) {
            throw new \Exception('setType expected an unsigned char in the range of 0-255');
        }
        $this->type = $type;
        return $this;
    }

    /**
     * @return string
     */
    public function getUnsignedFunctionID()
    {
        return $this->unsignedFunctionID;
    }

    /**
     * @param int $unsignedFunctionID
     *
     * @return PacketShortAccess
     * @throws Exception
     */
    public function setUnsignedFunctionID($unsignedFunctionID)
    {
        if (
            false === is_int($unsignedFunctionID) ||
            $unsignedFunctionID < 0 ||
            $unsignedFunctionID > 255
        ) {
            throw new \Exception('setUnsignedFunctionID expected an unsigned char in the range of 0-255');
        }
        $this->unsignedFunctionID = $unsignedFunctionID;
        return $this;
    }

    /**
     * @return int
     */
    public function getReserved()
    {
        return $this->reserved;
    }

    /**
     * @param int $reserved
     *
     * @return PacketShortAccess
     * @throws Exception
     */
    public function setReserved($reserved)
    {
        if (
            false === is_int($reserved) ||
            $reserved < 0 ||
            $reserved > 65535
        ) {
            throw new \Exception('setReserved expected an unsigned short in the range of 0-65535');
        }
        $this->reserved = $reserved;
        return $this;
    }

    /**
     * @return int
     */
    public function getUnsignediDevSn()
    {
        return $this->unsignediDevSn;
    }

    /**
     * @param int $unsignediDevSn
     *
     * @return PacketShortAccess
     * @throws Exception
     */
    public function setUnsignediDevSn($unsignediDevSn)
    {
        if (
            false === is_int($unsignediDevSn) ||
            $unsignediDevSn < -2147483648 ||
            $unsignediDevSn > 2147483647
        ) {
            throw new \Exception('setUnsignediDevSn expected a signed int in the range of -2147483648-2147483647');
        }
        $this->unsignediDevSn = $unsignediDevSn;
        return $this;
    }

    /**
     * @return string
     */
    public function getData()
    {
        return $this->data;
    }

    /**
     * @param string $data
     *
     * @return PacketShortAccess
     * @throws Exception
     */
    public function setData($data)
    {
        if (
            false === is_string($data) ||
            strlen($data) > 32
        ) {
            throw new \Exception('setData expected a string in the range of 0-32 characters');
        }
        $this->data = $data;
        return $this;
    }

    /**
     * @return int
     */
    public function getSequenceId()
    {
        return $this->sequenceId;
    }

    /**
     * @param int $sequenceId
     *
     * @return PacketShortAccess
     * @throws Exception
     */
    public function setSequenceId($sequenceId)
    {
        if (
            false === is_int($sequenceId) ||
            $sequenceId < 0 ||
            $sequenceId > 4294967295
        ) {
            throw new \Exception('setSequenceId expected a signed int in the range of 0-4294967295');
        }
        $this->sequenceId = $sequenceId;
        return $this;
    }

    /**
     * @return string
     */
    public function getExternData()
    {
        return $this->externData;
    }

    /**
     * @param string $externData
     *
     * @return PacketShortAccess
     * @throws Exception
     */
    public function setExternData($externData)
    {
        if (
            false === is_string($externData) ||
            strlen($externData) > 20
        ) {
            throw new \Exception('setExternData expected a string in the range of 0-20 characters');
        }
        $this->externData = $externData;
        return $this;
    }

    /**
     * @return string
     */
    public function __toString()
    {
        return sprintf(
            '%d %s %d %d % 32s %d % 20s',
            $this->getType(),
            $this->getUnsignedFunctionID(),
            $this->getReserved(),
            $this->getUnsignediDevSn(),
            $this->getData(),
            $this->getSequenceId(),
            $this->getExternData()
        );
    }

}

Using struct

$packetShortAccess = new PacketShortAccess;

$packetShortAccess
    ->setType(0x19)
    ->setUnsignedFunctionID(0x20)
    ->setReserved(0)
    ->setUnsignediDevSn(128495)
    ->setData('')
    ->setSequenceId(0)
    ->setExternData('')
;

echo "'" . (string)$packetShortAccess . "'"; // quotes added so you can see whitespace.

Will output this

'25 32 0 128495                                  0                     '

Upvotes: 2

Related Questions