php利用socket扩展写一个简单的单进程http服务1

废话少说,直接贴代码了。

<?php
	
	error_reporting(E_ALL);
	set_time_limit(0);
	ob_implicit_flush();
	date_default_timezone_set("Asia/Shanghai"); 


	$debug = true;
	
	function response_method_404(){
		$result = "";
		$result .="HTTP/1.1 404\r\n";
		$result .="Content-Length: 14\r\n";
		$result .= "Content-Type: text/html\r\n";
		$result .="\r\nserver is not \r\n";
		return $result;
	}
	
	function response_file_404(){
		$result = "";
		$result .="HTTP/1.1 404\r\n";
		$result .="Content-Length:0\r\n";
		$result .= "Content-Type: text/html\r\n";
		$result .="\r\n\r\n";
		return $result;
	}
	
	function response_file_type_404(){
		$result = "";
		$result .="HTTP/1.1 404\r\n";
		$result .="Content-Length:11\r\n";
		$result .= "Content-Type: text/html\r\n";
		$result .="\r\ntype is not\r\n";
		return $result;
	}
	
	function response_file_img($fileurl){
		$body = file_get_contents($fileurl);
		$len = strlen($body);
		$result="";
		$result .="HTTP/1.1 200\r\n";
		$result .="Content-Length:$len\r\n";
		$result .= "Content-Type: {$size['mime']}\r\n";
		$result .="\r\n$body\r\n";
		return $result;
	}
	
	
	function response_file_js($fileurl){
		global $request;
		$body = file_get_contents($fileurl);
		$len = strlen($body);
		$date = date('D, d M Y G:i:s ').'GMT';
		clearstatcache();
		$last_modified = date('D, d M Y G:i:s ',filemtime($fileurl)).'GMT';
		$result="";

		if ( $request['If-Modified-Since'] && $last_modified <= $request['If-Modified-Since'] ){
			$result .="HTTP/1.1 304\r\n";
		}else{
			$result .="HTTP/1.1 200\r\n";
			$result .="Cache-Control: public\r\n";
			$result .="Date:$date\r\n";
			$result .="Last-Modified:$last_modified\r\n";
			$result .="Expires:Fri, 24 Jan 2016 10:06:05 GMT\r\n";
			$result .="Content-Length:$len\r\n";
			$result .= "Content-Type: application/x-javascript\r\n";
			$result .="\r\n$body\r\n";
		}
		return $result;
	}
	
	
	function response_file_html($fileurl){
		$body = file_get_contents($fileurl);
		$len = strlen($body);
		$result = "";
		$result .="HTTP/1.1 200\r\n";
		$result .="Content-Length:$len\r\n";
		$result .= "Content-Type: text/html;charset=utf-8\r\n";
		$result .="\r\n$body\r\n";
		return $result;
	}
	
	function pare_request($str){
		global $web_root,$request;
		$arr = explode("\r\n",$str);
		foreach( $arr as $r){
			$pos = stripos($r,":");
			if ( $pos ){
				$key = trim(substr($r,0,$pos));
				$val = trim(substr($r,$pos+1));
				$request[$key] = $val;
			}

		}
		writelog(var_export($request,true));	
		$line0 = explode(" ",$arr[0]);
		if ( $line0[0] == "GET" ){
			$fileurl = $web_root.$line0[1];
			if ( file_exists($fileurl) ){
				$pathinfo = pathinfo($fileurl);
				if ( $pathinfo['extension'] == "js" ){
					$result = response_file_js($fileurl);
				}else if ( $pathinfo['extension'] == "png" || $pathinfo['extension'] == "jpg" || $pathinfo['extension'] == "gif" ){
					$result = response_file_img($fileurl);
				}else if ( $pathinfo['extension'] == "html" ){
					$result = response_file_html($fileurl);
				}else{
					$result = response_file_type_404();
				}
			}else{
				$result = response_file_404();
			}
		}else{
			$result = response_method_404();
		}
		return $result;
	}
	
	function sig_handler($signo) 
	{

	     switch ($signo) {
			 case SIGTERM:
				// 处理中断信号
			    exit;
			    break;
			 case SIGHUP:
			    // 处理重启信号
			    break;
			default:
			    // 处理所有其他信号
			}

	}


	function writelog($msg){
		global $debug;
		if ( $debug ){
			echo $msg;
		}else{
			file_put_contents('./log.txt',$msg,FILE_APPEND | LOCK_EX);
		}
	}
	
	if ( !$debug ){
		//产生子进程分支
		$pid = pcntl_fork();
		if ($pid == -1) {
			 writelog("could not fork\r\n");
			die("could not fork"); //pcntl_fork返回-1标明创建子进程失败
		} else if ($pid) {
			 exit(); //父进程中pcntl_fork返回创建的子进程进程号
		} else {
			 // 子进程pcntl_fork返回的时0
		}

		// 从当前终端分离
		if (posix_setsid() == -1) {
			writelog("could not detach form terminal \r\n");
			die("could not detach from terminal");
		}

		// 安装信号处理器
		pcntl_signal(SIGTERM, "sig_handler");
		pcntl_signal(SIGHUP, "sig_handler");

	}

	$address = '127.0.0.1';
	$port = 1215;
	$web_root = "/home/xtgxiso";
	$request = array();

	if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
		writelog("socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n");
		exit;
	}
	
	if (socket_bind($sock, $address, $port) === false) {
	    writelog("socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n");
		exit;
	}else{
		writelog('Socket ' . $address . ':' . $port . " has been opened\n");
	}
	
	if (socket_listen($sock, 5) === false) {
	    writelog("socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n");
		exit;
	}else{
		writelog("Listening for new clients..\n");
	}
	
	$client_id = 0;

	do{
		
		if ( ($msgsock = socket_accept($sock)) === false ) {
	        writelog("socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n");
	        break;
	    } else {
		    $client_id += 1;
			writelog("Client #" .$client_id .": Connect\n");
		}

		
		$cur_buf = '';
		do {
			if (false === ($buf = socket_read($msgsock, 2048))) {
				 writelog("socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n");
				 break;
			}
			writelog("read start:\r\n");
			writelog($buf);
			writelog("read end:\r\n\r\n");
			$talkback = pare_request($buf);
			writelog("write start:\r\n");
			socket_write($msgsock, $talkback, strlen($talkback));
			//writelog($talkback);
			writelog("write end:\r\n\r\n\r\n");
			break;
		} while (true);

		socket_close($msgsock);


	}while(true);

	writelog("socket_close \r\n");
	socket_close($sock);

实现了解析html,js,png,jpg,gif这几种格式的支持

这只是简单说明了一下思路,非常有利于大家了解http协议和优化其他http服务

as the women on the judging panel Guilana Rancik
snooki weight loss Oreimo Gets North American Simulcast Deal

and once soft
pornoRachel McAdams love triangle and baby bump rumors
cartoon porn
此条目发表在 好文推荐, 网站开发, 网站架构 分类目录,贴了 , 标签。将固定链接加入收藏夹。

评论功能已关闭。