0

2843

php的socket编程中socket_recv函数的应用

这两天在研究golang与php之间以socket通信,golang作为服务端,php作为客户端。

当传递普通数据时,php以socket_read接受数据一点问题都没有,但当服务端发送一张图片(二进制流)时,就会出现问题。

查看文档才发现,socket_read($socket, $len, PHP_NORMAL_READ)的第三参数不对,PHP_NORMAL_READ是用来接受字符数据,要改成PHP_BINARY_READ才能接收二进制流。

果断改成socket_read($socket, $len, PHP_BINARY_READ)后,然后再抛出到浏览器,果然可以显示图片了,兴奋了一下,但又发现了问题:浏览器显示图片时不时只显示一部分就断了。

图片随机性的只显示一部分,检查了流程都没问题。最后还是查官方文档,终于发现socket_recv函数:

(PHP 4 >= 4.1.0, PHP 5)
socket_recv — Receives data from a connected socket

说明

int socket_recv ( resource $socket , string &$buf , int $len , int $flags )
The socket_recv() function receives len bytes of data in buf from socket. socket_recv() can be used to gather data from connected sockets. Additionally, one or more flags can be specified to modify the behaviour of the function.

buf is passed by reference, so it must be specified as a variable in the argument list. Data read from socket by socket_recv() will be returned in buf.

其中,最后一个参数$flags要特别注意,先记录如下,以备国人知晓:

0x1 :数据应该带外发送,所谓带外数据就是TCP紧急数据

0x2 :使有用的数据复制到缓冲区内,但并不从系统缓冲区内删除。

0x4 :不要将包路由出去。

0x8 :数据完整记录

0x100 :数据完整处理

我从socket_recv($socket, $buf, $len, 0x1)一直测试到socket_recv($socket, $buf, $len, 0x100),最终确定用0x100才可以。

OK,问题解决了。

乐果   发表于   2015 年 01 月 24 日 标签:PHP 继续阅读

3

5648

php的pack函数应用

如题,最近在用PHP写socket的客户端,用到了pack函数。因此记录下:

    /**
     * 测试链路是否能正常通信
     * @author      liuxiang <unphp@qq.com>
     * @date        2015-01-22
     * @return boolean
     */
    public function ping()
    {
        $pool = $this->_pool;
        $sendData = pack('A60', 'ping');
        $sendCount = $this->fiexLenInfo($sendData);
        $command = pack('a10', $sendCount) . $sendData;
        socket_write($pool, $command, strlen($command));
        $len_buff = @socket_read($pool, 10, PHP_NORMAL_READ);
        $len = (int) trim($len_buff);
        if ($len >= 5 && '200' === trim(@socket_read($pool, 5, PHP_NORMAL_READ)))
        {
            return true;
        }
        return false;
    }

    /**
     * 请求socket服务接口
     * @author      liuxiang <unphp@qq.com>
     * @date        2014-12-26
     * @param type $address   调用的接口名(内部路由地址)
     * @param type $data      发送的数据
     * @return type
     */
    public function send($address, $data = '')
    {
        $pool = $this->connect();
        $sendData = pack('A60', $address) . $data;
        $sendCount = $this->fiexLenInfo($sendData);
        $command = pack('a10', $sendCount) . $sendData;
        socket_write($pool, $command, strlen($command));
        $len_buff = @socket_read($pool, 10, PHP_NORMAL_READ);
        $len = (int) trim($len_buff);
        if ($len >= 5)
        {
            $code = @socket_read($pool, 5, PHP_NORMAL_READ);
            $rp = 5 === $len ? '' : @socket_read($pool, $len - 5, PHP_NORMAL_READ);
            $rs = new coreServerResult($code, $rp);
            return $rs;
        }
        else
        {
            App::error('服务返回数据异常!', 50003);
        }
        return null;
    }

乐果   发表于   2015 年 01 月 22 日 标签:PHP 继续阅读

0

3286

PHP实现“贝格尔编排法”算法

在单循环积分淘汰赛中,经常会用到贝格尔编排法

今天在项目的比赛规则中就用到了,我用PHP实现“贝格尔编排法”如下:

    /**
     * 贝格尔编排法(算法)
     * @param int $n
     * @return array
     */
    function berger($n){
            if ($n < 3)
            {
                    return 0;
            }
            $h = (1 == $n % 2) ? 0 : $n;
            $num = $h > 0 ? $n : $n + 1;

            $average = $num/2;
            $rs1 = array();
            for($i = 0; $i < $average; $i++){
                    $top = $i+1;
                    $temp = array();
                    for($j = 0; $j < $num-1; $j++){
                         if($top>$num-1){
                                 $top = 1;
                         }
                         $temp[] = $top;
                         $top++;
                    }
                    $temp[] = $h;
                    $rs1[] = $temp;
            }

            $rs2 = array();
            for($i = $average; $i < $n; $i++){
                    $top = (($top+2)>($num-1)) ? $top = 1 : $top+2;
                    $temp = array();
                    $temp[] = $h;
                    for($j = 0; $j < $num-1; $j++){
                         if($top>$num-1){
                                 $top = 1;
                         }
                         $temp[] = $top;
                         $top++;
                    }
                    $rs2[] = $temp;
            }

            $rs = array();
            foreach ($rs1 as $k => $v)
            {
                    $rs[] = $v;
                    if(isset($rs2[$k])){
                            $rs[] = $rs2[$k];
                    }
            }
            return $rs;
    }

乐果   发表于   2014 年 12 月 23 日 标签:算法 继续阅读

0

3238

xapian主从部署

一、实际需求

在一个实际的大型部署中,检索的客户端往往以remote方式对索引库进行检索,而非files进行检索。 这是因为大型应用中,因负载较大,单台已经不能支撑起整个检索的任务。

remote是以tcp协议走socket接口,这样就可以将检索任务独立出来进行部署。 实际上,仅仅独立部署还是不够的,当负载进一步加大,就需要分布式部署,最简单的方式就是设置“一主多从”—即主从部署。

其中有一台“主服务”负责索引库的写入(更新),其他的“从服务”定期从“主服务”中批量更新并负责读取(检索)。

二、实际部署步骤

现在假设有两台服务器

a 192.168.1.50

b 192.168.1.60

其中,我们计划将a作为主服务器使用,b作为从服务器。部署步骤如下:

1、主服务器 ip 192.168.1.50

启动remote服务,假设检索库名称就叫xapian,把它创建在了/data目录下:

sudo ./xapian-tcpsrv -i 0.0.0.0 -p 8008 -w /data/xapian
Starting writable server on port 8008
Listening...

设置replicate服务:

sudo ./xapian-replicate-server -p 8009 -I 0.0.0.0 /data/

2、从服务器 ip 192.168.1.60

启动定时同步复制服务:

sudo ./xapian-replicate -h 192.168.1.50 -p 8009 -i 1 -v -m xapian /data/xapian

启动remote服务:

sudo ./xapian-tcpsrv -i 0.0.0.0 -p 8008 -w /data/xapian
Starting writable server on port 8008
Listening...

OK,至此,主从部署配置完成,非常简单。

声明:本站所有博文均为本人原创,引用请保留链接出处!

乐果   发表于   2014 年 12 月 02 日 标签:xapian 继续阅读

0

3490

xapian安装(PHP版)

1、scws安装

sudo wget http://www.xunsearch.com/scws/down/scws-1.2.2.tar.bz2
sudo tar -jxvf scws-1.2.2.tar.bz2
cd scws-1.2.2/
./configure --prefix=/usr/local/scws
sudo make && make install
sudo mkdir /usr/include/scws
ln -sf /usr/local/scws/include/scws /usr/include
sudo ln -s /usr/local/scws/lib/libscws.so.1.1.0 /usr/lib/libscws.so
sudo ln -s /usr/local/scws/lib/libscws.so.1.1.0 /usr/lib/libscws.so.1

安装scws扩展 cd phpext phpize ./configure –with-php-config=PHP_HOME/bin/php-config make make install

下载分词库

http://www.xunsearch.com/scws/down/scws-dict-chs-utf8.tar.bz2
sudo tar -jxvf scws-dict-chs-utf8.tar.bz2
cd scws-dict-chs-utf8
sudo mv dict.utf8.xdb /usr/local/scws/

2、安装xapian核心服务

sudo wget http://oligarchy.co.uk/xapian/1.2.17/xapian-core-1.2.17.tar.xz
sudo xz -d xapian-core-1.2.17.tar.xz
sudo tar xvf xapian-core-1.2.17.tar
cd xapian-core-1.2.17
sudo ./configure –prefix=/usr/local/xapian  

如果 报错:

configure: error: Neither uuid/uuid.h nor uuid.h found - required for brass, chert and flint (you may need to install the uuid-dev, libuuid-devel or e2fsprogs-devel package)

ubuntu环境下安装依赖库即可:

sudo apt-get install uuid-dev 

报错:

You need a working C++ compiler to compile Xapian
....
xapian ./configure CXX=/opt/bin/c++

ubuntu环境下安装依赖库即可:

sudo apt-get install g++

3、安装xapian客户端(php扩展)

sudo wget http://oligarchy.co.uk/xapian/1.2.17/xapian-bindings-1.2.17.tar.xz
sudo xz -d xapian-bindings-1.2.17.tar.xz
sudo tar xvf xapian-bindings-1.2.17.tar
cd xapian-bindings-1.2.17
sudo ./configure XAPIAN_CONFIG=/usr/local/xapian/bin/xapian-config --with-php PHP_CONFIG=/opt/service/php/bin/php-config

乐果   发表于   2014 年 11 月 29 日 标签:xapianPHPubuntu 继续阅读

较旧的文章 较新的文章
热评文章