<?php

/**
 * Class ClientSentCommand此类封装了一些网络操作实现,可以向指定IP和端口号发送指定的数据<br>
 *
 */
require_once 'Iobuffer.php';
require_once "SocketConnException.php";

class ClientSentCommand
{
    /**
     * 服务器端IP
     */
    private  $mServerIp;
    /**
     * 服务器端口号
     */
    private $mServerPort;
    /**
     * 通讯密匙
     */
    private $key = "";

    public function __construct($serverIp, $serverPort,$key = "")
    {
        $this->mServerIp = $serverIp;
        $this->mServerPort = $serverPort;
        $this->key = $key;
    }

    /**
     * 向指定的IP和端口号发送命令和数据,命令和数据以commandLen+command+$commandParamLen+$commandParam
     * 组成
     * @param $command
     * @param $commandParam
     * @return string
     */
    public function sendCommand($command,$commandParam)
    {
        $buf = new Iobuffer();
        $buf->putIntToBuf(strlen($command));
        $buf->putStrToBuf($command);

        if($this->mServerIp != "127.0.0.1")
        {
            $buf->putIntToBuf(strlen($this->key));
            $buf->putStrToBuf($this->key);
        }

        $buf->putIntToBuf(strlen($commandParam));
        $buf->putStrToBuf($commandParam);

        $sendData = $buf->getBuf();

        $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
		if(!$socket)
		{
			 throw new SocketConnException("create socket error!!!");
		}
        $result = socket_connect($socket, $this->mServerIp, $this->mServerPort);

        if(!$result)
        {
            throw new SocketConnException("can't connect the AMS server!");
        }


        // 向服务器发送数据
        for ($j = 0; $j < count($sendData); $j++)
        {
            socket_write($socket, chr($sendData[$j]));  // 逐数据发送
        }

        //在开始接收数据前,将buf复位
        $buf->bufRest();
        //接收服务器返回后的数据
        //从流中提取前4字节获取数据的长度
        $dataLen_binary = socket_read($socket, 4, PHP_BINARY_READ);  // 采用2进制方式接收数据
        $dataLen_hex = bin2hex($dataLen_binary);  // 将2进制数据转换成16进制
        $array_hex = str_split($dataLen_hex,2);  // 将16进制数据转换成两个一组的数组,这个数组中的十六进制全是字符，需要转换
        $real_hex = array();
        foreach($array_hex as $val)
        {
            $real_hex[]= intval($val,16);
        }

        $buf->putToBuf($real_hex);
        $dataLen = $buf->getInt();
        $buf->bufRest();

        //开始读取具体数据的字节流.
        $left = 0;
        $left = $dataLen;
        while ($left>0)
        {
            $data_binary = socket_read($socket, 100, PHP_BINARY_READ);  // 采用2进制方式接收数据
            $data_hex = bin2hex($data_binary);  // 将2进制数据转换成16进制
            $array_hex = str_split($data_hex,2);  // 将16进制数据转换成两个一组的数组,这个数组中的十六进制全是字符，需要转换
            $real_hex = array();
            foreach($array_hex as $val)
            {
                $real_hex[]= intval($val,16);
            }

            $n = count($real_hex);
            $left-=$n;
            $buf->putToBuf($real_hex);
        }

        $data = $buf->getStr();
        $buf->bufRest();

        socket_close($socket);

        return $data;
    }

    static function main_test()
    {
        $command = "ListLiveInfos";
        $commandData = "";

        $clientSentCommand = new ClientSentCommand("127.0.0.1",1936);
        $recv = $clientSentCommand->sendCommand($command,$commandData);

        echo "recv mesg:".$recv;
    }

}

?>