php socket(服务器和客户端范例)
php实现异步,用socket是一个不错的选择。
把下面两个文件保存为server.php和client.php,其中server.php可以直接用CLI命令行执行(php server.php),client.php可用http访问。当然全部用cli或全部用http都OK。
server.php
<?php
/**
* bsykc-20161101-SOCKET通讯
* 服务端9s
*
*/
error_reporting(E_ALL);
set_time_limit(0);
//ob_implicit_flush();
$address = '127.0.0.1';
$port = 31000;//提供服务的端口
//创建服务端口
if( ($handle = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
//写日志-服务器出错
echo 'serverError.socket_create()failed:' . socket_strerror(socket_last_error()) . "\n";
exit();
}
//绑定服务端口
if (socket_bind($handle, $address, $port) === false) {
//写日志-服务器出错
echo 'serverError.socket_bind()failed' . socket_strerror(socket_last_error($handle)) . "\n";
exit();
}
//监听服务端口
if (socket_listen($handle, 5) === false) {
//写日志-服务器出错
echo 'serverError.socket_listen()failed:' . socket_strerror(socket_last_error($handle)) . "\n";
exit();
}
echo 'serverRuning...'."\n";
//遍历接收客户端的信息
do {
//得到一个链接conn
if (($conn = socket_accept($handle)) === false) {
//写日志-服务器出错
echo 'serverError.socket_accept()failed:'.socket_strerror(socket_last_error($handle)) . "\n";
exit();
break;
}
//模拟IO等操作延迟返回
$num = 0;
/*for($i=0;$i<100000;$i++){$num+= rand(1,2);}*/
//welcome 发送到客户端
//$msg = 'serverResponse:'."\n";//返回给客户的信息
//socket_write($conn, $msg, strlen($msg));//写进缓冲区
//读取客户端提交的数据
$result = 'receivedMessage:'."\n";
echo "\n".'----------clientMessage:'.microtime().'-----------'."\n";
$buf = socket_read($conn, 8192);
$result.= $buf;
echo $result;//
echo "\n".'----------clientMessage:'.microtime().'-----------'."\n\n";
//返回给用户
$result = 'ImServer,thisMessageForYou,serverTime:'.microtime().'NUM='.$num;
if (false === socket_write($conn, $result, strlen($result))) {
//写日志-服务器出错
echo 'serverError.socket_write()failed:' . socket_strerror(socket_last_error($handle)) ."\n";
exit();
} else {
echo 'send2ClientSuccess.';
}
socket_close($conn);
echo "\n\n"."\n\n"."\n\n"."\n\n";
} while(true);
//关闭socket
socket_close($handle);
?>
client.php
<?php
/**
* bsykc-20161101-SOCKET通讯
* 客户端9b
*
*/
//error_reporting(E_ALL);
echo 'TCP/IP connecting...'.'<br/>';
$addressHost = '127.0.0.1';
$servicePort = 31000;
//创建一个套接字
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
echo 'clientError.socket_create()failed:' . socket_strerror(socket_last_error()).'<br/>';
exit();
} else {
echo 'socketCreateSuccess.'.'<br/>';
}
//创建链接
$result = socket_connect($socket, $addressHost, $servicePort);
if($result === false) {
echo 'clientError.socket_connect()failed: '. $result . socket_strerror(socket_last_error($socket)).'<br/>';
exit();
} else {
echo 'connectSuccess. '.$addressHost.':'.$servicePort.'<br/>';
}
//拼接缓冲数据
$data = 'HEAD / http/1.1'."\n";
$data .= 'HOST: localhost '."\n";
$data .= 'Connection: close';
echo 'sendingHttpHeadRequest ...'.'<br/>';//发送给服务器
socket_write($socket, $data, strlen($data));
echo 'sendSuccess.OK'.'<br/>';//发送成功
//循环遍历返回-可不接收返回-即实现了异步
define('CFG_SOCKET_WAIT', 5);//等待返回时间,如果为0则不等待返回
if (CFG_SOCKET_WAIT > 0){
echo 'readingResponse:';
echo '<br/>'.'----------serverMessage:'.microtime().'-----------'.'<br/>';
$out = '';
while ($out = socket_read($socket, 8192)) {
echo $out;
}
echo '<br/>'.'----------serverMessage:'.microtime().'-----------'.'<br/><br/>';
}else{
echo 'CFG_SOCKET_WAIT!=0';
}
echo 'closeingSocket...'.'<br/>';
socket_close($socket);
echo 'closeSuccess,clientTime:'.microtime().'<br/>';