http服务是建立在tcp服务之上的,它是tcp/ip协议的应用,前面我们已经实现了tcp服务,并且使用三种不同的方式连接tcp服务
既然http也是tcp应用层的一种,那么我们直接使用浏览器来连接tcp服务可不可以?答案是可以的,只不过连接之后直接返回给浏览器的信息,浏览器不能够正确的识别出来。那么怎么才能让浏览器正确的识别tcp服务返回的信息呢?
这个时候我们就需要使用到http协议啦,至于http传输中都传了哪些信息可以在浏览器中 f12 查看
http_serv.php文件
<?php
/**
* Http 服务器类
*/
class Http{
private $host;
private $port;
private $_root;
public $mime_types = array(
\'avi\' => \'video/x-msvideo\',
\'bmp\' => \'image/bmp\',
\'css\' => \'text/css\',
\'doc\' => \'application/msword\',
\'gif\' => \'image/gif\',
\'htm\' => \'text/html\',
\'html\' => \'text/html\',
\'ico\' => \'image/x-icon\',
\'jpe\' => \'image/jpeg\',
\'jpeg\' => \'image/jpeg\',
\'jpg\' => \'image/jpeg\',
\'js\' => \'application/x-javascript\',
\'mpeg\' => \'video/mpeg\',
\'ogg\' => \'application/ogg\',
\'png\' => \'image/png\',
\'rtf\' => \'text/rtf\',
\'rtx\' => \'text/richtext\',
\'swf\' => \'application/x-shockwave-flash\',
\'wav\' => \'audio/x-wav\',
\'wbmp\' => \'image/vnd.wap.wbmp\',
\'zip\' => \'application/zip\',
);
/**
* @param string $host 监听地址
* @param int $port 监听端口
* @param string $_root 网站根目录
*/
public function __construct($host,$port,$_root){
$this->host = $host;
$this->port = $port;
$this->_root = $_root;
}
/**
* 启动http服务
*/
public function start(){
//创建socket套接字
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//设置阻塞模式
socket_set_block($socket);
//为套接字绑定ip和端口
socket_bind($socket,$this->host,$this->port);
//监听socket
socket_listen($socket,4);
while(true)
{
//接收客户端请求
if(($msgsocket = socket_accept($socket)) !== false){
//读取请求内容
$buf = socket_read($msgsocket, 9024);
preg_match("/\/(.*) HTTP\/1\.1/",$buf,$matchs);
preg_match("/Accept: (.*?),/",$buf,$matchss);
//获取接收文件类型
$type = explode("/",$matchss[1])[0];
if($type=="text"){
$content = $this->GetString($matchs[1]);
}else{
$content = $this->GetImg($matchs[1]);
}
socket_write($msgsocket,$content,strlen($content));
socket_close($msgsocket);
}
}
}
/**
* 组装消息头信息模板
* @param int $code 状态码
* @param string $status 状态名称
* @param string $content 发送的文本内容
* @param string $content_type 发送的内容类型
* @return string
**/
public function GetHeaders($code,$status,$content="",$content_type="text/html;charset=utf-8"){
$header = \'\';
$header .= "HTTP/1.1 {$code} {$status}\r\n";
$header .= "Date: ".gmdate(\'D, d M Y H:i:s T\')."\r\n";
$header .= "Content-Type: {$content_type}\r\n";
$header .= "Content-Length: ".strlen($content)."\r\n\r\n";//必须2个\r\n表示头部信息结束
$header .= $content;
return $header;
}
/**
* 组装文本发送信息
* @param string $url_path
* @return string
**/
public function GetString($url_path){
if($this->getRealPath($url_path)){
if(is_readable($this->getRealPath($url_path))){
return $this->GetHeaders(200,"OK",file_get_contents($this->getRealPath($url_path)),$this->getMime($url_path));
}else{
return $this->GetHeaders(401,"Unauthorized");
}
}else{
return $this->GetHeaders(404,"Not Found");
}
}
/**
* 组装资源返回信息
* @param string $url_path
* @return string
**/
public function GetImg($url_path){
if($this->getRealPath($url_path)){
return $this->GetHeaders(200,"OK",file_get_contents($this->getRealPath($url_path)),$this->getMime($url_path));
}else{
return $this->GetHeaders(404,"Not Found");
}
}
/**
* 获取资源类型
* @param string $path
* @return mixed
*/
public function getMime($path){
$type = explode(".",$path);
$mime = $this-> mime_types[$type[1]];
return $mime;
}
/**
* 获取访问资源的真实地址
* @param $url_path
* @return bool|string
*/
public function getRealPath($url_path){
return realpath($this->_root."/".$url_path);
}
}
$server = new Http("127.0.0.1",3046,"wwwroot");
$server->start();
效果图:
github地址: https://github.com/enjoysmilehappy/http_server
链接:https://www.cnblogs.com/itsuibi/p/11139112.html