telnet到设备里 php_玩转 PHP 网络编程首篇

64100aaa009099c18dcb153f6c0bb9d3.png

先扯蛋

本来有点想删掉了【一直在草稿里呆好久了,想想还是发布吧,兴许可能有人用得上】
laravel 里的系列文章功能用得不顺手,不知道咋搞的,我就直接粗暴的粘链接了。时间原因,本来是想再深入的,想想有机会再补充吧。


玩转 PHP 网络编程全套阻塞与非阻塞IO
玩转 PHP 网络编程全套之 socket 选项设置 API
玩转 PHP 网络编程全套之数据接收与发送
玩转 PHP 网络编程全套之 unix 本地域 socket 通信
玩转 PHP 网络编程全套之 I/O 复用
玩转 PHP 网络编程全套之 socket stream 函数编程
玩转 PHP 网络编程全套之 libevent 框架首篇
玩转 PHP 网络编程全套之 libevent 框架多人聊天应用
玩转 PHP 网络编程全套之 libevent 框架之 httpServer
玩转 PHP 网络编程全套之中断系统编程
玩转 PHP 网络编程全套之多进程编程
网络框架workerman源码图文完整分析

PHP socket 手册

手册地址:https://www.php.net/manual/zh/book.sockets.php

使用需求

系统平台fec53fdf1b6c46fb8904839ad15a2bee.png

php -m 或 php --ri sockets

d430cc49451a838dcd40b847edd3b8ec.png

显示如上,表示php已经支持socket扩展

几行代码先运行

$ip = "0.0.0.0";
$port = $argv[1];
$sockefd = socket_create(AF_INET,SOCK_STREAM,0);
echo $sockefd.PHP_EOL;
$pid = posix_getpid();
echo "pid=".$pid.PHP_EOL;
echo `ls -al /proc/{$pid}/fd`;//为了方便看该进程生成的数据
socket_bind($sockefd,$ip,$port);
socket_listen($sockefd,5);

while (1){}

然后我php socket1.php 12345
结果显示如下8754793a9db93705274454fcdb8c0113.png
我先来解释先
Resource id #4那是PHP返回的,在PHP里称为资源
0 它是一个字符输入设备也是文件描述符【linux皆文件】
1 它是一个字符输出设备也是文件描述符
2 同样的也是
3 比较特殊它是一个epoll类型的文件,链接着一个匿名节点
4 是一个socket类型的文件,它的结点是9460457
5 是一个管道文件
实际上我去对应的目录看是没有这文件的,可以先不理它
在linux上它是这样的bae520c394846395520c17742fe60b93.png接下来我们继续看socket:[9460457]->4
先看它的网络状态,我们 cat net/tcp 即可22fbec637d5b5a0cd17e4be04d2152fb.png
先对几个重要的选项解释一下
local_address 表示本地ip和端口号用16进制表示
rem_address 远程服务器ip和端口
st 表示套接字状态
1 TCP_ESTABLISHED
2 TCP_SYN_SENT
3 TCP_SYN_RECV
4 TCP_FIN_WAIT1
5 TCP_FIN_WAIT2
6 TCP_TIME_WAIT
7 TCP_CLOSE
8 TCP_CLOSE_WAIT
9 TCP_LAST_ACK
10 TCP_LISTEN 16进制就是A
11 TCP_CLOSING
tx_queue 发送队列中的数据长度
rx_queue 接收的数据长度
tr 定时器类型
0 未启动定时
1 开启socket 定时重传机制
2 开启持续定时
3 开启连接定时器 FIN_WAIT2定时
4 TIME_WAIT定时

tm->when 超时时间
retrnsmt 超时重传次数
uid 用户的id
inode socket套接字对应的结点inode
大家都了解TCP数据流拥有自己的接收缓冲区和发送缓冲区,同时呢具有超时重传机制和数据应答确诊机制

这个socket它的状态用netstat -antp查看就是这样的fbe9b8e7609bbcd36387dca086f3d1e0.png

所以我们socket_create后它创建了一个TCP并且处于监听状态中即LISTEN。

我们在代码的最后一句加上了while就是让它一直循环在那运行R(running),我们在该进程生成的目录下可以查看eda02e0222fb8220344d17bcfe5b0ee5.png

发起一个网络连接一下看看效果

在发起连接之前我们先要执行tcpdump -i lo port 12345
然后使用telnet工具去连接,得到的结果如下c2351d1116f3046413c71a4791f51b40.png
22:33:44.827309 IP localhost.37510 > localhost.italk: Flags [S], seq 1537400892
01:50:55.605018 IP localhost.italk > localhost.37510: Flags [S.], seq 1228325870, ack 1537400893
22:33:44.827328 IP localhost.37510 > localhost.italk: Flags [.], ack 1

前面的是时间,localhost.37510是客户端的ip和系统分配的随机端口
而localhost.italk是本机Flags

  • SYN 表示发起一个连接

  • ACK 一个应答

  • RST 重新发起连接

  • PSH 在传输数据时会有这个标志位

  • URG 紧急标志位

  • FIN 一个关闭报文

seq 表示源IP向目标IP传输的序列号
对端应答的时候必须在其基础上加1操作
ack 表示确认序列号,一般在seq上加1进行应答确认
以上的内容完成了大家比较熟悉的TCP连接三次握手

我想知道细节,想知道它到底在干嘛

下面我来添加几句代码,我们来更清楚的知道它们是怎么玩在一起的,是怎么进行通信的

....
while (1){

$connfd = socket_accept($sockefd);
echo $connfd.PHP_EOL;
socket_write($connfd,"hello,php 是世界上是好的语言");

}

然后输入如下命令

strace -f php socket1.php 12345

抽核心大概流程

  • exec4087ca4656c3ef683535478d2bc83804.png

  • read socket1.php54e3c664234c72b5b5848002c8e3c622.png

  • create socket9dbb04ed5ca0ca10b4638f27aaed8ed7.png

  • exec shb5152a51ff7a63e2760f61922673f0de.png

  • bind,listen,accept658d0f117a12a3b95415b571161b860b.png
    就大概这么几句,创建socket返回文件描述符4,然后bind绑定,监听,最后呢在accept函数阻塞进程【Sleeping状态】cpu已经做其它事情了,毕竟它在”睡觉中”1484ba5f67b62e62bc5fb4928faf5ac8.png5b84abdd8573414d5999325ad25a187a.png

接下来我们同样用 telnet 工具来连接并传输数据cc5b9f9b3cb74169b20b77c34753f8ce.pngc1b2169f6fb998f7ad2cf8bc0566393b.png4c58eb3401468ad5e955815ad7f982ba.png

1874a0f413b5c895061479154a8e3b7e.png

接下来我们再加几句代码让其它成基本的响应给客户端

while (1){
$connfd = socket_accept($sockefd);
echo $connfd.PHP_EOL;
socket_write($connfd,"hello,php 是世界上是好的语言");
echo socket_read($connfd,4098,PHP_BINARY_READ);
}

876fe95ad0cdc982b1b0e1e4c1b09bba.png

我们看到 php 语言低层调用了 libc API【任何语言都是一样】
都是先创建一个 socketfd ,再把端口和地址绑架到它身上,再 listen 进行监听,直到 accept 阻塞,有客户端连接时才会唤醒该进程来处理数据。所以务必动手实验才能领略阻塞和唤醒的感觉。

e8381c28ddbf1064986086193512c0c1.png


ddb6600f81aac8a84471e57c123b5dd6.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值