【php socket通讯】php实现http服务

【php socket通讯】php实现http服务
  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();
 
  效果图:
 
  

推荐阅读