玩转 PHP 网络编程首篇

先扯蛋

本来有点想删掉了【一直在草稿里呆好久了,想想还是发布吧,兴许可能有人用得上】
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 手册

手册地址

使用需求

系统平台
玩转PHP网络编程全套

php -m 或 php --ri sockets

玩转PHP网络编程全套

显示如上,表示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
结果显示如下
玩转PHP网络编程全套
我先来解释先
Resource id #4那是PHP返回的,在PHP里称为资源
0它是一个字符输入设备也是文件描述符【linux皆文件】
1它是一个字符输出设备也是文件描述符
2同样的也是
3比较特殊它是一个epoll类型的文件,链接着一个匿名节点
4是一个socket类型的文件,它的结点是9460457
5是一个管道文件
实际上我去对应的目录看是没有这文件的,可以先不理它
在linux上它是这样的
玩转PHP网络编程全套
接下来我们继续看socket:[9460457]->4
先看它的网络状态,我们cat net/tcp即可
玩转PHP网络编程全套
先对几个重要的选项解释一下
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 定时重传机制
4开启持续定时
2开启连接定时器 FIN_WAIT2定时
3 TIME_WAIT定时

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

这个socket它的状态用netstat -antp查看就是这样的
玩转PHP网络编程全套

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

我们在代码的最后一句加上了while就是让它一直循环在那运行R(running),我们在该进程生成的目录下可以查看
玩转PHP网络编程全套

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

在发起连接之前我们先要执行tcpdump -i lo port 12345
然后使用telnet工具去连接,得到的结果如下
玩转 PHP 网络编程全套
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

抽核心大概流程

  • exec
    玩转 PHP 网络编程全套
  • read socket1.php
    玩转 PHP 网络编程全套
  • create socket
    玩转 PHP 网络编程全套
  • exec sh
    玩转 PHP 网络编程全套
  • bind,listen,accept
    玩转 PHP 网络编程全套
    就大概这么几句,创建socket返回文件描述符4,然后bind绑定,监听,最后呢在accept函数阻塞进程【Sleeping状态】cpu已经做其它事情了,毕竟它在”睡觉中”
    玩转 PHP 网络编程全套
    玩转 PHP 网络编程全套

接下来我们同样用telnet工具来连接并传输数据
玩转 PHP 网络编程全套
玩转 PHP 网络编程全套
玩转 PHP 网络编程全套

玩转 PHP 网络编程全套

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

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

玩转 PHP 网络编程全套

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

玩转 PHP 网络编程全套

本作品采用《CC 协议》,转载必须注明作者和本文链接
只会php crud的渣渣
本帖由系统于 4个月前 自动加精
勺颠颠
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 35

这些天你是憋了一个大招啊 :grin:

5个月前 评论
勺颠颠

@L学习不停 放在草稿里好长时间了,本来想全删除了,但是有的用户可能会用得上,我就全一起发了,时间原因,本来想后面再发了,想想草稿里大堆看的碍眼 :joy:

5个月前 评论
勺颠颠

@L学习不停 :blush:

5个月前 评论
勺颠颠

@mmmm :smirk:

4个月前 评论
Dennis_Ritchie

:+1: :+1: :+1:

4个月前 评论

没想到CPU竟然如此喜欢装逼和划水~ :joy:

4个月前 评论
勺颠颠

@DamonYan :joy:

4个月前 评论

大佬写文章就是不一样,哈哈

4个月前 评论
勺颠颠

@Wi1dcard 一般一般 :joy:

4个月前 评论
勺颠颠
4个月前 评论

写的很详细,就是看不懂😂

4个月前 评论
勺颠颠

@mmmm php手册都有示例的,认真看基本都能理解的

4个月前 评论
hxd

超出我的理解能力上限了

4个月前 评论
勺颠颠

@hxd php就是这样的啊😂

4个月前 评论

先mark后看

4个月前 评论
勺颠颠

@Arsenal_jie :relaxed:

4个月前 评论

稍微指正几点

strace看到的不是libc API, 而是系统调用

并不是所有语言都会使用libc

4098应该是想写4096吧, 通常正好是一页内存的大小

4个月前 评论

@twosee 大佬还是出现了

4个月前 评论
勺颠颠

@twosee tks

Laravel

file

file

4个月前 评论
╰ゝSakura

谢谢大佬,学习了,伸手党留言

4个月前 评论

谢谢大佬,先收藏 以后学习

4个月前 评论
勺颠颠

@AyuAyu :blush:

4个月前 评论
勺颠颠
4个月前 评论

膜拜大佬,先收藏再看

4个月前 评论
勺颠颠

@stonelalala :blush:

4个月前 评论
勺颠颠

@wpby :kissing_heart:

4个月前 评论
勺颠颠

@kaichang :blush:

3个月前 评论

厉害了,大佬

3个月前 评论
勺颠颠

@qianfan 一般一般 :kissing_heart:

3个月前 评论
勺颠颠

@景哥哥 :blush:

3个月前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!