PHP Socket详解

其实学习,最好的方法就是自己整理资料,分享给别人,通过整理能有更清晰的思路,不至于混成一锅粥,此外,能给别人讲清楚,说明你自己已经掌握了要点。

首先,对socket有个简单的认识,socket网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。


推荐一篇博客来熟悉socket的原理机制:

http://blog.csdn.net/hguisu/article/details/7445768/


总结:

Socket,从服务端的的角度来讲,最基本的就是三步走:

  创建->绑定->监听

从整个socket通信角度来讲,就是:

服务端监听->客户端连接并发送数据->服务端接收数据 (以及后续处理)。


以上基础掌握之后,我们再来学习一下如何进行socket多进程处理请求。这个是为了解决:

当一个连接长时间占用当前进程时,后面来的请求就必须要等待,这会导致处理请求的速度很低,那么解决的方案就是,使用多个进程,当每发来一个请求时,就开启一个进程进行处理,为了区别单进程和多进程的区别,我们还是看一下代码是如何写的:


首先是单进程服务端代码:

<?php

$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_bind($socket,'127.0.0.1',9090) or die('error');
socket_listen($socket,5);

while(true){
    $client = socket_accept($socket);   // 有人打电话进来
    $buf = socket_read($client,1024);   // 一次读取1024的长度
    echo $buf;

    if(preg_match('/sleep/i',$buf)){
        sleep(10);

        $html = 'HTTP/1.1 200 OK'.PHP_EOL
            .'Content-Type: text/html;charset=utf-8'.PHP_EOL.PHP_EOL;
        socket_write($client,$html);
        socket_write($client,'this is server,休克了10秒,模拟很繁忙的样子');
    }else{
        socket_write($client,'this is server');
    }

    socket_close($client);
}

socket_close($socket);


多进程的代码:

<?php

$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_bind($socket,'127.0.0.1',9090) or die('error');
socket_listen($socket,5);

while(true){
    $client = socket_accept($socket);

    //创建紫金城
    $pid = pcntl_fork();
    //父进程和子进程都会执行下面代码
    if ($pid == -1) {
        //错误处理:创建子进程失败时返回-1.
        die('could not fork');
    } else if ($pid) {
        //父进程会得到子进程号,所以这里是父进程执行的逻辑
        //pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
        socket_close($client);
    } else {
        //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
        $buf = socket_read($client,1024);
        echo $buf;
        if(preg_match('/sleep/i',$buf)){
            sleep(10);
            $html = 'HTTP/1.1 200 OK'.PHP_EOL
                .'Content-Type: text/html;charset=utf-8'.PHP_EOL.PHP_EOL;
            socket_write($client,$html);
            socket_write($client,'this is server,休克了10秒,模拟很繁忙的样子');
        }else{
            socket_write($client,'this is server');
        }
        socket_close($client);
    }
}

socket_close($socket);

这里重点是掌握

pcntl_fork()这个函数的使用,如果没有安装这个拓展的需要安装一下;

<?php

$pid = pcntl_fork();
//父进程和子进程都会执行下面代码
if ($pid == -1) {
    //错误处理:创建子进程失败时返回-1.
     die('could not fork');
} else if ($pid) {
     //父进程会得到子进程号,所以这里是父进程执行的逻辑
     pcntl_wait($status); //等待子进程中断,防止子进程成为僵尸进程。
} else {
     //子进程得到的$pid为0, 所以这里是子进程执行的逻辑。
}

?>


这是php.net 手册里给的案例,看不懂的可以去查一下手册;


但是很明显,采用这样的多进程处理方式,当请求成千上万时,开销很大,所以显然不是高效的,如何优化呢,此处推荐一篇博客:

http://blog.csdn.net/hguisu/article/details/7448528











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值