php下Socket服务器如何搭建并测试?(代码)

php下Socket服务器如何搭建并测试?(代码)

内容导读

收集整理的这篇技术教程文章主要介绍了php下Socket服务器如何搭建并测试?(代码),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5133字,纯文字阅读大概需要8分钟

内容图文

本篇文章给大家带来的内容是关于php下Socket服务器如何搭建并测试?(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

1、socket服务器搭建思路

1) 目的:理解socket服务器工作机制

2) 思路:创建socket -> 把socket加入连接池 -> 处理接收信息 -> 握手动作 -> 发送信息

2、socket服务器代码

注:复制到php文件,直接命令行可以运行,不需要其他支持

特别注意:为了能传输中文_sendMsg做了json_encode()

<?php/** * Socket服务器 * @author wuchangliang 2018/1/17 */class SocketServer{

private $sockets; //连接池

private $master;

private $handshake;

/**

 * @param $address

 * @param $port

 */

public function run($address, $port)

{



//配置错误级别、运行时间、刷新缓冲区



echo iconv('UTF-8', 'GBK', "欢迎来到PHP Socket测试服务。 n");



error_reporting(0);



set_time_limit(0);



ob_implicit_flush();



//创建socket



$this->master = $this->_connect($address, $port);



$this->sockets[] = $this->master;



//运行socket



while (true) {





$sockets = $this->sockets;





$write = NULL;





$except = NULL;





socket_select($sockets, $write, $except, NULL); //$write,$except传引用





foreach ($sockets as $socket) {







if ($socket == $this->master) {









$client = socket_accept($socket);









$this->handshake = false;









if ($client) {











$this->sockets[] = $client; //加入连接池









}







} else {









//接收信息









$bytes = @socket_recv($socket, $buffer, 2048, 0);









if ($bytes <= 6) {











$this->_disConnect($socket);











continue;









};









//处理信息









if (!$this->handshake) {











$this->_handshake($socket, $buffer);









} else {











$buffer = $this->_decode($buffer);











$this->_sendMsg($buffer, $socket);









}







}





}



}

}

/**

 * 创建socket连接

 * @param $address

 * @param $port

 * @return resource

 */

private function _connect($address, $port)

{



//创建socket



$master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)



or die("socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "n");



socket_bind($master, $address, $port)



or die("socket_bind() failed: reason: " . socket_strerror(socket_last_error($master)) . "n");



socket_listen($master, 5)



or die("socket_listen() failed: reason: " . socket_strerror(socket_last_error($master)) . "n");



return $master;

}

/**

 * 握手动作

 * @param $socket

 * @param $buffer

 */

private function _handshake($socket, $buffer)

{



//握手动作信息



$buf = substr($buffer, strpos($buffer, 'Sec-WebSocket-Key:') + 18);



$key = trim(substr($buf, 0, strpos($buf, "rn")));



$new_key = base64_encode(sha1($key . "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", true));



$new_message = "HTTP/1.1 101 Switching Protocolsrn";



$new_message .= "Upgrade: websocketrn";



$new_message .= "Sec-WebSocket-Version: 13rn";



$new_message .= "Connection: Upgradern";



$new_message .= "Sec-WebSocket-Accept: " . $new_key . "rnrn";



//记录握手动作



socket_write($socket, $new_message, strlen($new_message));



$this->handshake = true;

}

/**

 * 断开socket连接

 * @param $socket

 */

private function _disConnect($socket)

{



$index = array_search($socket, $this->sockets);



socket_close($socket);



if ($index >= 0) {





array_splice($this->sockets, $index, 1);



}

}

/**

 * 发送信息

 * @param $buffer

 * @param $client

 */

private function _sendMsg($buffer, $client)

{



$send_buffer = $this->_frame(json_encode($buffer));



foreach ($this->sockets as $socket) {





if ($socket != $this->master && $socket != $client) { //广播发送(除了自己)







socket_write($socket, $send_buffer, strlen($send_buffer));





}



}

}

/**

 * 解析数据帧

 * @param $buffer

 * @return null|string

 */

private function _decode($buffer)

{



$len = $masks = $data = $decoded = null;



$len = ord($buffer[1]) & 127;



if ($len === 126) {





$masks = substr($buffer, 4, 4);





$data = substr($buffer, 8);



} else if ($len === 127) {





$masks = substr($buffer, 10, 4);





$data = substr($buffer, 14);



} else {





$masks = substr($buffer, 2, 4);





$data = substr($buffer, 6);



}



for ($index = 0; $index < strlen($data); $index++) {





$decoded .= $data[$index] ^ $masks[$index % 4];



}



return $decoded;

}

/**

 * 处理返回帧

 * @param $buffer

 * @return string

 */

private function _frame($buffer)

{



$len = strlen($buffer);



if ($len <= 125) {





return "x81" . chr($len) . $buffer;



} else if ($len <= 65535) {





return "x81" . chr(126) . pack("n", $len) . $buffer;



} else {





return "x81" . char(127) . pack("xxxxN", $len) . $buffer;



}

}}$sc = new SocketServer();$sc->run('127.0.0.1', 2046);

3、客户端代码

注:直接复制到html,和上面的php文件在同一文件夹即可,特别注意onmessage解析的两层 parse

<!DOCTYPE html><html><head>

<meta charset="utf-8" />

<title>WebSocket Test</title>

<script language="javascript"type="text/javascript">



websocket = new WebSocket('ws://127.0.0.1:2046/');



websocket.onopen = function(evt) {





console.log('connect');





websocket.send('{"data":"您好,世界!"}');



};



websocket.onclose = function(evt) {





console.log('onclose');





console.log(evt);



};



websocket.onmessage = function(evt) {





console.log('onmessage');





if (evt.data) {







console.log(JSON.parse(JSON.parse(evt.data)));





}



};



websocket.onerror = function(evt) {





console.log('onerror');





console.log(evt);



};



function sendMsg(){





var sendData = { 'data': document.getElementById('name').value};





websocket.send(JSON.stringify(sendData));



}

</script></head><body>

<h2>WebSocket Test</h2>

<input type="text" name="name" id="name" />

<a href="javascript:;" onclick="sendMsg()">点击发送</a></body></html>

4、测试示例

相关推荐:

PHP中Socket服务器搭建和测试方法教程

Nodejs如何搭建Web服务器

以上就是php下Socket服务器如何搭建并测试?(代码)的详细内容,更多请关注Gxl网其它相关文章!

内容总结

以上是为您收集整理的php下Socket服务器如何搭建并测试?(代码)全部内容,希望文章能够帮你解决php下Socket服务器如何搭建并测试?(代码)所遇到的程序开发问题。 如果觉得技术教程内容还不错,欢迎将网站推荐给程序员好友。

内容备注

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。


本文关键词:

联系我们

在线咨询:点击这里给我发消息

邮件:w420220301@qq.com