http服务是建立在tcp服务之上的,它是tcp/ip协议的应用,前面我们已经实现了tcp服务,并且使用三种不同的方式连接tcp服务
php中连接tcp服务的三种方式
既然http也是tcp应用层的一种,那么我们直接使用浏览器来连接tcp服务可不可以?答案是可以的,只不过连接之后直接返回给浏览器的信息,浏览器不能够正确的识别出来。那么怎么才能让浏览器正确的识别tcp服务返回的信息呢?
这个时候我们就需要使用到http协议啦,至于http传输中都传了哪些信息可以在浏览器中f12查看
目录结构:
http_serv.php文件
<?php
/**
*Http服务器类
*/
classHttp{
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',
);
/**
*@paramstring$host监听地址
*@paramint$port监听端口
*@paramstring$_root网站根目录
*/
publicfunction__construct($host,$port,$_root){
$this->host=$host;
$this->port=$port;
$this->_root=$_root;
}
/**
*启动http服务
*/
publicfunctionstart(){
//创建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);
}
}
}
/**
*组装消息头信息模板
*@paramint$code状态码
*@paramstring$status状态名称
*@paramstring$content发送的文本内容
*@paramstring$content_type发送的内容类型
*@returnstring
**/
publicfunctionGetHeaders($code,$status,$content="",$content_type="text/html;charset=utf-8"){
$header='';
$header.="HTTP/1.1{$code}{$status}\r\n";
$header.="Date:".gmdate('D,dMYH:i:sT')."\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;
}
/**
*组装文本发送信息
*@paramstring$url_path
*@returnstring
**/
publicfunctionGetString($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,"NotFound");
}
}
/**
*组装资源返回信息
*@paramstring$url_path
*@returnstring
**/
publicfunctionGetImg($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,"NotFound");
}
}
/**
*获取资源类型
*@paramstring$path
*@returnmixed
*/
publicfunctiongetMime($path){
$type=explode(".",$path);
$mime=$this->mime_types[$type[1]];
return$mime;
}
/**
*获取访问资源的真实地址
*@param$url_path
*@returnbool|string
*/
publicfunctiongetRealPath($url_path){
returnrealpath($this->_root."/".$url_path);
}
}
$server=newHttp("127.0.0.1",3046,"wwwroot");
$server->start();
效果图:
|