<?php /* socket链接整个过程 1,socket_create 第一个参数指定应用程序使用的通信协议的协议族,对于TCP/IP协议族,该参数置AF_INET; 第二个参数指定要创建的套接字类型,流套接字类型为SOCK_STREAM、数据报套接字类型为SOCK_DGRAM、原始套接字SOCK_RAW(WinSock接口并不适用某种特定的协议去封装它,而是由程序自行处理数据包以及协议首部); 第三个参数指定应用程序所使用的通信协议。此参数可以指定单个协议系列中的不同传输协议。在Internet通讯域中,此参数一般取值为0,系统会根据套接字的类型决定应使用的传输层协议。 2,socket_connect 3,socket_write 4,socket_read 5,socket_close */ Class Client { static private $socket = null; public function __construct() { //不报错 error_reporting(0); //引入数据库 require_once('conn.php'); if(self::$socket == null) self::$socket = socket_create(AF_INET,SOCK_STREAM,0); if(self::$socket === false) exit('create socket fail! please check it!' . $this->err()); } //连接并发送数据 public function conn($ip,$port,$data) { //数组数据序列号保存发送 $data = serialize($data); if(!socket_connect(self::$socket,$ip,$port)) exit('socket connect error!' . $this->err()); if(socket_write(self::$socket,$data) === false) exit('socket write error!' . $this->err()); } //获取数据 public function getBack() { $res = socket_read(self::$socket,4096); if($res === false) exit('socket read error !' . $this->err()); if($res) return $res; else return 'nothing return'; } //析构释放资源 public function __destruct() { socket_close(self::$socket); } //错误 private function err() { return socket_strerror(socket_last_error()); } }
<?php /* socket 服务器通信整个过程 socket_creat socket_bind socket_listen socket_accetp socket_read socket_write socket_close 注:1,服务器需要开启php 的pcntl系列扩展, 2,服务器必须开通对应端口,而且需跟客户端请求端口一致 */ //监听客户端触发, class Message { private $socket = null; public function __construct($info) { $this->init($info); //子程序结束后,系统自动回收,避免产生僵尸进程 pcntl_signal(SIGCLD, SIG_IGN); pcntl_signal(SIGCHLD,SIG_IGN); //dojob $this->doJob(); } //初始化 private function init($info) { //创建通信 if(!$this->socket = socket_create(AF_INET,SOCK_STREAM,0)) exit('error: create fail!' . $this->err()); //绑定端口 if(!socket_bind($this->socket,$info['ip'],$info['port'])) exit('error: bind fail' . $this->err()); //监听端口 if(!socket_listen($this->socket)) exit('error: listen fail' . $this->err()); } //处理数据 public function doJob() { do{ //接受一个通信 $mes_sock = socket_accept($this->socket); if($mes_sock === false) exit('error: accept fail!' . $this->err()); //读取到客户端传送过来的数据 $mes_client = socket_read($mes_sock,4096); if($mes_client === false) exit('error: read fail' . $this->err()); $data = unserialize($mes_client); //开始分进程 $pid = pcntl_fork(); if($pid) { //父进程 $remeg = ''; if($data['type'] == 1) $remeg = 'request ok!'; else $remeg = 'allow ok!'; //将消息返回 if(socket_write($mes_sock,$remeg) === false) exit('error: write fail' . $this->err()); }else { require_once('Db.class.php'); $conn = Db::getInstance(array('ip'=>'192.168.1.11','user'=>'root','pass'=>'123456','database'=>'test')); //子进程 if($data['type'] == 1) { //处理用户申请加入圈子,当消息发送成功后,更改数据库信息 echo "处理用户申请加入圈子\n"; //$sql ="UPDATE test_add SET status = 1 WHERE status "; die; }else{ //处理圈主审核 echo "处理圈主审核\n"; die; } } //释放资源 socket_close($mes_sock); }while(1); } //错误 private function err() { return socket_strerror(socket_last_error()); } //析构释放 public function __desctruct() { socket_close($this->socket); } } //运行 $message = new Message(array('ip'=>'192.168.1.6','port'=>'1935'));
//附属的db类
<?php /* 数据库类 */ class Db { //用于存放实例化的对象 static private $_instance = null; //公共静态方法获取实例化的对象 static protected function getInstance($data) { if (!(self::$_instance instanceof self)) { self::$_instance = new self($data); } return self::$_instance; } //私有克隆 private function __clone() {} //私有构造 private function __construct($data) { $conn = mysql_connect($data['ip'],$data['user'],$data['pass']); if(!$conn) exit('数据库连接错误!' . mysql_error()); mysql_query('set names utf8'); mysql_query('use '. $data['database']); } }
可以实现客户端请求后,服务器立马返回数据,通知客户端请求成功。再子进程处理。而且不会有defunct僵尸进程。