对socket的代码学习和自我理解与记录

编程

<?php

class Worker{

//监听socket

protected $socket = NULL;

//连接事件回调

public $onConnect = NULL;

//接收消息事件回调

public $onMessage = NULL;

public $workerNum=4; //子进程个数

public $allSocket; //存放所有socket

public function __construct($socket_address) {

//监听地址+端口

$this->socket=stream_socket_server($socket_address);

stream_set_blocking($this->socket,0); //设置非阻塞,这个主要影响资源流读取是不是阻塞1阻塞0非阻塞 非阻塞的时候会立即返回,不管有没有读取到,主要影响到的函数fgets() 和 fread()

$this->allSocket[(int)$this->socket]=$this->socket;//存放所有socket资源

}

public function start() {

$this->fork();

}

public function fork(){

$this->accept();

}

public function accept(){

while (true){

$write=$except=[];

//需要监听socket

$read=$this->allSocket;

//状态谁改变

stream_select($read,$write,$except,60);//这里是阻塞的,第五个参数没传默认是null(stream_select阻塞等待时间超过($tv_sec+$tv_usec)的时间总值,如果$tv_sec=&null时,则无限阻塞直到上面4种返回条件中的任何一种发生了)

            //有状态变化后,比如可读状态

//怎么区分服务端跟客户端

foreach ($read as $index=>$val){

//当前发生改变的是服务端,有连接进入

if($val === $this->socket){

$clientSocket=stream_socket_accept($this->socket); //阻塞监听,服务器可读状态变化,照理来说这里应该是不会被阻塞的或者说应该很快读到数据

//触发事件的连接的回调

if(!empty($clientSocket) && is_callable($this->onConnect)){

call_user_func($this->onConnect,$clientSocket);//和$this->onConnect($clientSocket);好像等价

}

$this->allSocket[(int)$clientSocket]=$clientSocket;

}else{

//从连接当中读取客户端的内容

$buffer=fread($val,1024);//原本阻塞,上面设置过,不阻塞了

//如果数据为空,或者为false,不是资源类型

if(empty($buffer)){

if(feof($val) || !is_resource($val)){//feof是否已经到文件末尾

//触发关闭事件

fclose($val);

unset($this->allSocket[(int)$val]);

continue;

}

}

//正常读取到数据,触发消息接收事件,响应内容

if(!empty($buffer) && is_callable($this->onMessage)){

call_user_func($this->onMessage,$val,$buffer);

}

}

}

}

}

}

$worker = new Worker("tcp://0.0.0.0:9805");

//连接事件

$worker->onConnect = function ($fd) {

//echo "连接事件触发",(int)$fd,PHP_EOL;

};

//消息接收

$worker->onMessage = function ($conn, $message) {

//事件回调当中写业务逻辑

//var_dump($conn,$message);

$content="学习过程";

$http_resonse = "HTTP/1.1 200 OK

";

$http_resonse .= "Content-Type: text/html;charset=UTF-8

";

$http_resonse .= "Connection: keep-alive

"; //连接保持

$http_resonse .= "Server: php socket server

";

$http_resonse .= "Content-length: ".strlen($content)."

";

$http_resonse .= $content;

fwrite($conn, $http_resonse);//数据写入资源句柄

};

$worker->start(); //启动

以上是 对socket的代码学习和自我理解与记录 的全部内容, 来源链接: utcz.com/z/511844.html

回到顶部