小编给大家分享一下PHP Swoole与tcp的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!握手常见问题连接拒绝Operation now in pro
小编给大家分享一下PHP Swoole与tcp的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
连接拒绝
Operation now in progress 多是因为丢包、错误ip、backlog满了&阻塞&tcp_abort_on_overflow=0
min(maxconn, backlog) ss -lt
在TCP三次握手的时候,客户端发送SYN这个包给服务端,服务端不接受这个请求,操作系统直接返回了一个RST的包,来拒绝连接的请求。
最常见的情况就是客户端去请求某个服务器,服务端没有绑定对应的端口。
测试代码如下,服务端代码:
<?php$server = new \Swoole\Server('127.0.0.1', 9501);$server->set([ 'work_num' => 2, 'backlog' => 128,]);$server->on('connect', function ($server, $fd){ echo "Client: Connect.\n";});$server->on('receive', function ($server, $fd, $Reactor_id, $data){ var_dump($data);});$server->on('close', function (){ var_dump('close');});$server->start();
这里,服务端绑定的端口是9501。
启动服务器:
1 ~/codeDir/phpCode/hyperf-skeleton # php server.php
客户端代码:
<?php$client = new \Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);var_dump($client->connect('127.0.0.1', 9500));
这里,客户端请求的端口是9500。
启动客户端:
~/codeDir/phpCode/hyperf-skeleton # php client.php Warning: Swoole\Client::connect(): connect to server[127.0.0.1:9500] failed, Error: Connection refused[111] in /root/codeDir/phpCode/hyperf-skeleton/client.php on line 4bool(false)~/codeDir/phpCode/hyperf-skeleton #
报错:
Error: Connection refused[111]
这个错误的绝大部分原因是因为连接超时了。
例如路由器、网关出现了故障,包被丢了。
例如客户端请求了一个错误的ip,那么路由器自然也就路由不到。
测试代码如下,客户端代码:
<?php$client = new \Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC);var_dump($client->connect('8.8.8.8', 9501));
这里,我访问的是谷歌的DNS服务器。因为我没有FQ,所以是访问不了这个IP的。因此,我们发送的包是到达不了8.8.8.8服务器的。
启动客户端:
~/codeDir/phpCode/hyperf-skeleton # php client.php Warning: Swoole\Client::connect(): connect to server[8.8.8.8:9501] failed, Error: Operation in progress[115] in /root/codeDir/phpCode/hyperf-skeleton/client.php on line 4bool(false)~/codeDir/phpCode/hyperf-skeleton #
报错:
Error: Operation in progress[115]
服务器在三次握手的最后一次,即收到客户端发来的ACK包的时候,会把建立好的连接放到backlog队列里面。如果Swoole一直不accept连接,那么这个backlog队列很快就会满。backlog队列满了之后,服务端就会丢弃三次握手的SYN包,让客户端重新去连接服务端。
测试代码如下,服务端代码:
<?php$server = new \Swoole\Server('127.0.0.1', 9501, SWOOLE_BASE);$server->set([ 'work_num' => 2, 'backlog' => 128,]);$server->on('connect', function ($server, $fd){ echo "Client: Connect.\n"; sleep(1000);});$server->on('receive', function ($server, $fd, $reactor_id, $data){ var_dump($data);});$server->on('close', function (){ var_dump('close');});$server->start();
要想测试backlog问题必须在Swoole的SWOOLE_BASE模式下,默认的SWOOLE_PROCESS模式是没有这个问题的。
这里,我们的backlog大小是128。
然后,我们通过sleep(1000);来阻塞住进程,使得Swoole不会继续accept连接,从而导致backlog队列在某个时刻变满。
客户端代码:
<?php$i = 0;while (true){ $client = new \Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_SYNC); if ($client->connect('127.0.0.1', 9501) == false) { break; }}
我们启动服务器:
~/codeDir/phpCode/hyperf-skeleton # php server.php
然后启动客户端:
~/codeDir/phpCode/hyperf-skeleton # php client.php 省略了其他的输出bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)bool(true)Warning: Swoole\Client::connect(): connect to server[127.0.0.1:9501] failed, Error: Operation in progress[115] in /root/codeDir/phpCode/hyperf-skeleton/client.php on line 7bool(false)Warning: Swoole\Client::connect(): connect to server[127.0.0.1:9501] failed, Error: Operation in progress[115] in /root/codeDir/phpCode/hyperf-skeleton/client.php on line 7bool(false)^C~/codeDir/phpCode/hyperf-skeleton #
我们会发现,过一段时间,客户端这边会报错:
Error: Operation in progress[115]
服务端这边输出:
~/codeDir/phpCode/hyperf-skeleton # php server.php
Client: Connect.
因为当Swoole服务器从backlog队列里面accept一个连接的时候,才会触发onReceive回调函数。所以,当服务端accept一个连接之后,Swoole自己就会陷入阻塞,不会再accept了。但是需要注意的是,尽管Swoole服务器自身是阻塞的,操作系统还会继续去把建立好的连接放入backlog队列里面。所以,backlog队列会满。
除了三次握手成功之后会使用到的backlog队列,还有一个SYN队列。也就是在三次握手时候,客户端给服务端发送了SYN包,服务端会有一个SYN队列来维护。
与其有关的内核配置:
tcp_max_syn_backlogtcp_synack_retriestcp_syncookies
其中,tcp_max_syn_backlog就是这个SYN队列的长度。如果大量的SYN包把SYN队列塞满了,那么其他正常的连接过来,服务端就无法处理。
SYN Flood攻击就是客户端疯狂的给服务端发送SYN包,然后服务端每次都会把请求放到SYN队列里面。但是,客户端不给服务端回ACK包。如果客户端不回ACK包,那么服务端就会给客户端回SYN + ACK包,即第二次握手发送的包。而回复SYN + ACK包的次数就是由tcp_synack_retries参数决定的。如果把tcp_synack_retries设置为0,那么如果服务端没有收到ACK包,那么服务端就不会重试发送SYN + ACK包了,这样就减少了SYN队列里面那个请求的存活时间。
tcp_syncookies的原理就是,客户端发送SYN包的时候,不会维护SYN队列,而是返回一个cookie给客户端。然后客户端发送第三次握手的时候,携带这个cookie值,只有这个cookie验证通过,服务端才会给连接分配资源。
php的框架:1、Laravel,Laravel是一款免费并且开源的PHP应用框架。2、Phalcon,Phalcon是运行速度最快的一个PHP框架。3、Symfony,Symfony是一款为WEB项目准备的PHP框架。4、Yii,Yii是一款快速、安全和专业的PHP框架。5、CodeIgniter,CodeIgniter是一款非常敏捷的开源PHP框架。6、CakePHP,CakePHP是一款老牌的PHP框架。7.Kohana,Kohana是一款敏捷但是功能强大的PHP框架。
以上是“PHP Swoole与TCP的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网PHP编程频道!
--结束END--
本文标题: PHP Swoole与TCP的示例分析
本文链接: https://lsjlt.com/news/278277.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0