短文1:使用 php-socket 简述 http 服务器原理

此节使用 PHP 原生 Socket 演示完成 http 请求的原理

套接字怎么理解

一个典型的网络连接由 2 个套接字构成,一个运行在客户端,另一个运行在服务器端。

“套接字”取名叫做 socket,翻译:“插座”。在网络编程中叫做用于网络数据传输的“软件设备”。

那么通俗理解一点,“套接字” 就是一个文件资源 file

socket 示意图

以一家拉面馆做比喻

流程概要:假设场景是食城,一家拉面店。通过 create 创建一个服务端套接字,初始化套接字有三个参数,是ipv4还是ipv6、面向连接还是面向消息、tcp 还是 udp ,也就是描述这个套接字是干嘛用,描述我是一家拉面馆。接下来通过 bind 端口号,也就是联系地址,食城第123号能找到我。通过 listen 开始监听,准备好了开始营业(这时店里没人接待,顾客排队等候)。调用 accept 函数等待客户端连接(此处阻塞,直到有客户端连接产生一个客户端文件描述符 fd ),也就是等待客人,直到来了一个顾客,此时店员拿起一张纸片问顾客问吃点啥,随后将纸片转给后厨。后厨 read 纸片上的菜品,然后准备食物 响应,然后 write 给顾客。顾客走了,卡片也就没用了扔掉了(fd回收),socket_close($client) 结束该顾客的服务。晚上10点,拉面店关门,socket_close($server)

PHP 代码

创建一个套接字,$server 表示的是服务端的套接字。描述我是拉面馆。

$server = socket_create(
AF_INET, 
SOCK_STREAM, 
SOL_TCP);

绑定端口号,0.0.0.0 服务所有人,当然也可以是专供

socket_bind($socket, '0.0.0.0', 80);

开始监听,5 排队中等待接待的顾客人数,地方小门口只能站5个人(资源层面)。

socket_listen($socket, 5);

与一个客户端建立连接,接待了张三

$client = socket_accept($server);

读取客户端信号,张三:⌈来大碗拉面加个蛋⌉,服务员拿纸记录下来

$buf = socket_read($client, 1024);

处理信号,后厨阅读纸片,制片内容如下

$content = 'hello! i am server!';
$http_resonse = "HTTP/1.1 200 OK\r\n"; $http_resonse .= "Content-Type: text/html;charset=UTF-8\r\n"; $http_resonse .= "Connection: keep-alive\r\n"; $http_resonse .= "Server: php socket server\r\n"; $http_resonse .= "Content-length: ".strlen($content)."\r\n\r\n"; $http_resonse .= $content;

向客户端写入信号,上菜品

socket_write($client,$http_resonse);

关闭客户端,资源回收。系统创建的资源描述符是有限的(因为每个资源描述符都要打开输入输出缓冲区,如果不及时回收资源,内存就会被占满)

socket_close($client);

关闭服务端,店面关门

socket_close($server);

处理信号

上边读取到客户端的信号buf,如果我请求的地址是这样:
请求  URL
打印buf:
socket 打印buf
buf是一长串字符串,用正则来匹配该字符串:

$preg = '#GET (.*) HTTP/1.1#iU';
preg_match($preg, $buf, $arr);
$request = $arr[1];

匹配的 (.*)是:
uri
这样我们就拿到了请求的内容。

响应

如果是加载静态页面:

静态页面
获取的文件名是
静态页面文件名
那么 $response是:

$filePath = __DIR__ . '/html' . $path;
$content = file_get_contents($filePath);

如果是 php 文件:

请求的是php文件
获取的文件名是:
获取的文件名是
那么 $response 是:

$filePath = __DIR__ . '/php' . $path;
ob_start();
include $filePath; //这里执行了一段php逻辑代码
$content = ob_get_contents();
ob_clean();
本作品采用《CC 协议》,转载必须注明作者和本文链接
welcome come back
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
95
粉丝
24
喜欢
156
收藏
347
排名:323
访问:2.9 万
私信
所有博文
社区赞助商