php-pcntl+socket

php-pcntl+socket②

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<?php

class SocketServer
{

public $socket;

public $all_sockets = [];

public function __construct(string $address)
{
//创建监听socket服务 资源句柄 ,,resource|false
$this->socket = \stream_socket_server($address, $php_errorcode, $php_errormsg);

if ($this->socket == false) {
throw new \Exception('创建失败!', $php_errorcode, $php_errormsg);
}

\stream_set_blocking($this->socket, false);

//当前初始化的第一个socket服务 资源句柄放入 资源池
$this->all_sockets[intval($this->socket)] = $this->socket;
echo ('=== 服务器启动|' . $address.PHP_EOL);
}

public function run()
{
//死循环
while (true) {
$write=$except=null;
$allSocket=$this->all_sockets;
\stream_select($allSocket, $write, $except, 60);

foreach ($allSocket as $index => $socket) {
//如果 streamsocket 服务句柄 == 当前socket资源池的id,说明有新连接
if ($this->socket === $socket) {
// 接受由 stream_socket_server() 创建的套接字连接 timeout/覆盖默认的套接字接受的超时时限。输入的时间需以秒为单位
// resource|false
$new_conn_socket = \stream_socket_accept($this->socket);
if ($new_conn_socket == false) {
//可能是建立连接异常
continue;
}
$this->onConn($new_conn_socket);
$this->all_sockets[intval($new_conn_socket)] = $new_conn_socket;
echo '=== 新连接建立'.(int)($new_conn_socket).PHP_EOL;
} else {
//如果不是新的连接,则看看有无数据过来,读取长度 65536
$buff = fread($socket, 0xFFFF);
// 不能是 == ''
if ($buff === '' || $buff === false) {
//客户端已断开
echo '=== 断开连接'.intval($socket).PHP_EOL;
$this->onClose($socket);
unset($this->all_sockets[intval($socket)]);
fclose($socket);
continue;
}
//处理发来的数据
$this->onMessage($socket, $buff);
}
}
}
}


public function onConn(mixed $socket)
{

}

public function onClose(mixed $socket)
{
}

public function onMessage(mixed $socket, $buff)
{
$body = 'hello word';
$header = [
'HTTP/1.1 200 OK',
'Connection: keep-alive',
'Niubi: test123',
'Content-length:' . strlen($body)
];
$header_string = \implode(chr(0x0D) . chr(0x0A), $header);

$data = $header_string . chr(0x0D) . chr(0x0A) . chr(0x0D) . chr(0x0A) . $body;


// echo '用户数据:'.$buff.PHP_EOL;
fwrite($socket, $data);

unset($this->all_sockets[intval($socket)]);
fclose($socket);
}

}


$a = new SocketServer('tcp://0.0.0.0:88');
$a->run();;

php-pcntl+socket.png

作者

舰长胡椒

发布于

2022-08-19

更新于

2023-10-13

许可协议

评论