Socket学习 - 从这个角度学http协议就很简单了
来源:互联网 发布:宝鸡文理学院网络课程 编辑:程序博客网 时间:2024/05/21 14:03
回顾前面:Socket学习 - 开启Socket学习之旅
<?php$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); // 购买电话机socket_bind($socket,'127.0.0.1',9090); // 绑定电话机socket_listen($socket,5); // 开机while(true){ $client = socket_accept($socket); // 有人打电话进来 $buf = socket_read($client,1024); // 一次读取1024的长度 echo $buf; // 回复 socket_write($client,'hello socket'); socket_close($client); // 关掉客户端}socket_close($socket); // 关机
我们服务端server.php代码中echo $buf;
会输出HTTP协议的部分内容。
注意:是要浏览器访问的情况下,因为浏览器走了HTTP协议的。
同时我们也可以看到,虽然浏览器是通过HTTP协议的,但我们服务端并不用也遵守这个协议。
本节,我们就在socket来模拟一下HTTP协议。
1.先在项目下新建个html文件,便于我们测试
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body>这是静态新闻首页的内容</body></html>
然后我们浏览器这样访问:http://127.0.0.1:9090/news/index.html
2.我们在服务端server.php里来查看浏览器访问时,发送过来的数据。
<?php$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); // 购买电话机socket_bind($socket,'127.0.0.1',9090); // 绑定电话机socket_listen($socket,5); // 开机while(true){ $client = socket_accept($socket); // 有人打电话进来 $buf = socket_read($client,1024); // 一次读取1024的长度 echo $buf; if(preg_match("/GET\s\/(.*?)\sHTTP\/1.1/i",$buf,$matches)){ var_export($matches); } // 回复 socket_write($client,'hello socket'); socket_close($client); // 关掉客户端}socket_close($socket); // 关机
我们已经知道上面代码中echo $buf
就能读取到浏览器发送过来的HTTP内容,如下:
GET /news/index.html HTTP/1.1Host: 127.0.0.1:9090Connection: keep-aliveCache-Control: max-age=0Upgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding: gzip, deflate, sdch, brAccept-Language: zh-CN,zh;q=0.8,en;q=0.6
然后我们用正则匹配这部分内容,var_export($matches);
打印如下:
array ( 0 => 'GET /news/index.html HTTP/1.1', 1 => 'news/index.html',)
3.根据浏览器的请求,服务端回复内容
server.php
<?php$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); // 购买电话机socket_bind($socket,'127.0.0.1',9090); // 绑定电话机socket_listen($socket,5); // 开机while(true){ $client = socket_accept($socket); // 有人打电话进来 $buf = socket_read($client,1024); // 一次读取1024的长度 echo $buf; if(preg_match("/GET\s\/(.*?)\sHTTP\/1.1/i",$buf,$matches)){ $page_path = $matches[1]; // 文件在本地的路径 if(file_exists($page_path)){ $html_content = file_get_contents($page_path); //读取文件内容 //socket回复给客户端 socket_write($client,$html_content); }else{ socket_write($client,'404'); } }else{ // 回复 socket_write($client,'hello socket'); } socket_close($client); // 关掉客户端}socket_close($socket); // 关机
可以看到服务端确实把news\index.html
的内容返回给了浏览器。
4.回复复合要求的内容
我们已经把html文件的里的内容读取出来,并成功回复(响应到浏览器上了),但并不是我们理想的效果,原因就在于:我们并没有严格按照HTTP的协议响应数据给浏览器。
在socket_write
回复的数据,需要按照HTTP定义的格式来。
看代码:
<?php$socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); // 购买电话机socket_bind($socket,'127.0.0.1',9090); // 绑定电话机socket_listen($socket,5); // 开机while(true){ $client = socket_accept($socket); // 有人打电话进来 $buf = socket_read($client,1024); // 一次读取1024的长度 echo $buf; if(preg_match("/GET\s\/(.*?)\sHTTP\/1.1/i",$buf,$matches)){ $page_path = $matches[1]; // 文件在本地的路径 if(file_exists($page_path)){ //拼接HTTP响应格式 $html_content = 'HTTP/1.1 200 OK'.PHP_EOL .'Content-Type: text/html;'.PHP_EOL .PHP_EOL .file_get_contents($page_path); //socket回复给客户端 socket_write($client,$html_content); }else{ socket_write($client,'404'); } }else{ // 回复 socket_write($client,'hello socket'); } socket_close($client); // 关掉客户端}socket_close($socket); // 关机
然后浏览器访问http://127.0.0.1:9090/news/index.html
:
这样才是html文件在浏览器上的正确姿势。
希望从这个案例上,对理解HTTP协议有所帮助。
0 0
- Socket学习 - 从这个角度学http协议就很简单了
- 学习必须有耐性。。这个。我就纠结。学了javascript!
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关于HTTP协议,一篇就够了
- 关键字
- 蚂蚁宝卡套餐资费
- findBugs学习小结
- Java泛型
- laravel 打印sql
- Socket学习 - 从这个角度学http协议就很简单了
- 说说遇到的一个问题
- win10开启telnet服务
- 超级厉害的JavaScript —— ECMAScript 6 标准(3) —— 解构赋值
- Android微信抢红包功能的实现
- 4*4数组逆时针旋转90度
- 面试--排序(75)
- SpringMVC介绍之Validation
- dump_stack内核调试