linux下php多進程與可響應http請求的socket server


  要有多蛋疼才會用php去寫http服務器?答案是需要蛋疼到蛋裂的地步。

  還好哥只是略疼,所以寫了非常非常粗糙的一點東西,目的是為了溫習下php的socket(tcp)+fork的用法。

  開始先講原理,主要是scoket服務利用whilet掛住,socket_accept接收到新的socket連接后,馬上fork一個子進程,負責單獨和這個連接交互,這里也很簡單,無非就是socket_read掛住監聽這個連接的請求,發現有則解析並返回,這里說的返回是socket_write往socket連接的句柄寫入信息。

  接着就是代碼了,解釋再多也不如代碼看得實在。

#!/usr/local/php/bin/php
<?php
$host = "192.168.1.50"; $port = 12335;
set_time_limit(0);
// Socket create
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Could not create socket\n");
// Bind socket to a port
$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
// Start listening for connections
$result = socket_listen($socket, 3) or die("Could not set up socket listener\n");

while( true )
{
/** waiting a new connection **/
$newsock = socket_accept( $socket );
/**
***We fork child process for each client
*
*/
if($newsock)
{
$child = pcntl_fork();
if( $child > 0 )
{//parent process.
/**
** Since child process is hanging there.
** so we know that we should close client socket here.
*
*/
socket_close( $newsock );
}
else if( $child == 0 )
{//child process
/** get address and port of client socket **/
socket_getpeername($newsock,$addr,$port);
$welcomemsg = "A new clients $addr:$port was entered.".PHP_EOL;
echo $welcomemsg;
while( true )
{
/** hanging here to wait some messages come from client socket **/
$msg = socket_read( $newsock,1024);
if( $msg === false)
{
/** Client was quited unexpected **/
echo "$addr:$port was quited!".PHP_EOL;
socket_close( $newsock );
posix_kill( posix_getpid(),SIGTERM);
}
else
{
$kill = false;
$msg = strtolower(trim($msg));
/** Cli hello message **/
if(!empty($msg) && $msg != "\x21\x23") echo "$addr:$port request:".$msg.PHP_EOL;
/** Do something according to command from client **/
switch( $msg )
{
default :
if(preg_match('#^(get|post)\s+/([^\s]*)#i',$msg,$match))
{//it's a http request
$page = $match[2] ? $match[2] : 'index.php';
ob_start();
include '/var/www/'.$page;
$httpResponse = ob_get_contents();
ob_end_clean();
//$httpResponse = "<b>Hello browser,成功了!</b>";
$msg = "HTTP/1.1 200\n"
."Content-type:text/html;charset=utf-8\n"
."Content-length:".strlen($httpResponse)."\n"
."Connection:close\n\n"
.$httpResponse;
$kill = true;
}
else $msg = "Unknow command!";
break;
case "\x21\x23":
$msg = "Welcome $addr:$port";
break;

case 'q':
case 'quit':
case 'exit':
echo "$addr:$port ask for quit!".PHP_EOL;
break;
}
/** Message send to client socket,
*** would kill client socket when wrote action was fail or when we doing a http response*
*/
if(!socket_write($newsock,$msg,strlen($msg)) || $kill)
{
echo "$addr:$port was quited!".PHP_EOL;
socket_close( $newsock );
posix_kill( posix_getpid(),SIGTERM);
}
}
}
}
else
{//
exit('Unable to fork!');
}
}
}
// close sockets
socket_close($socket);
?>

  非常簡單吧!正如之前所說的那樣,什么?還想真的完成http請求的解析+依托cgi響應返回,丫沒病吧。

  趕緊來試驗下簡單的東西,首先啟動這個socket server服務

  啟動服務器

       然后先瀏覽80端口服務器的的某個html頁面

  80服務器

 

       然后看看php的scoket server響應效果

  php socket服務器

  賓了個果,妥了個妥地,再打開一個瀏覽器tab頁面,輸入這個地址+端口一樣可以正確看到效果。

  而且也看到了瀏覽器往我們傻缺的php http server服務器請求了以下信息。

  請求信息

  接下來如何改進這個php socket server玩玩好玩的東西呢?想到再說吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM