PHP TCP服务器的实现方式

2016/08/08
博文原创  复制请谨慎
学习记录下
该教程只是一个简单tcp服务器 自己手写下加深下印象
可以基于tcp实现http协议服务器  websocket协议服务器
基于read然后按照他们协议规定的拼装数据包就可以了
有想知道websocet怎么实现的,告诉我没事我加上
这个demo实现了群聊和单聊
key唯一生成,每次链接都不一样
当然这只是一个demo,如果想应用到自己项目中,最少还是要实现断开链接触发 心跳 多进程

直接上代码

class SocketServer{
	private $socket; //socket资源句柄
	private $userSocket = array(); //保存链接进来的套接字列表
	
	private $writeSocket = array(); //保存链接进来的套接字列表
	/**
	*初始化
	*@param String $host ip地址
	*@param int $port 端口
	*@param int $backlog 最大连接数
	*/
	public function __construct($host = '127.0.0.1',$port = '9337', $backlog = 10)
	{
		$this -> socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die('socket创建失败'); //创建socket
		socket_bind($this -> socket,$host,$port); //为socket绑定端口
		socket_listen($this -> socket,$backlog); //监听socket套接字并设置链接数  可以不设置
		$socketkey = $this -> generateRangNum();
		$this->userSocket[$socketkey] = $this -> socket; //把套接字保存到数组中 		
	}
	
	/**
	*启动woker实例
	*/
	public function runStart() {
		
		while(true) { //设置一个循环用来监听来自客户端的请求
			$socketList = $this->userSocket; //把读的socket放到变量中
			socket_select($socketList, $this->writeSocket , $except = null , null); //多路进行选择
			
			foreach ( $socketList as $socket ) {
				
				if($this->socket == $socket) { //说明当前的服务器监听socket //就开始设置请求的函数
					$client = socket_accept($this->socket); //接收客户端的链接
					//添加客户端套接字
					$userkey 	= $this->_addClient($client);	//把客户端的socket句柄添加到userSocket中
					
					$data = array(
						'success' => 'Welcome',
						'info' => $userkey
					);
					$datajson = json_encode( $data );
					
					socket_write($client,$datajson,strlen($datajson)); //触发链接后告诉客户端链接成功的信息
					
					//$this->sendAll();
					
				} else { 
					$msg = @socket_read($socket,1024);//获取客户端发送来的信息
					
					$msginfo = json_decode( $msg,true );
					
					if ( $msginfo['type'] =='all' ) { //发送所有人
						$this->sendAll();
					} else {
						$this->sendToUser( $msginfo['userkey'],$msginfo['info'] );
					}
					
					
				}
				
			}
		}
		
	}
	
	
	/**
	*@param resource $client 客户端的套接字
	*/
	private function _addClient($client) {
		$socketkey = $this -> generateRangNum();
		$this->userSocket[$socketkey] = $client;
		return $socketkey;
	}
	
	//对单用户socket发送
	public function sendToUser( $userkey,$info ) {
		
		$socket = $this->userSocket[$userkey];
		
		@socket_write($socket,$info,strlen( $info ));
		
	}
	
	
	//对所有socket发送
	public function sendAll() {
		
		$socketList = $this->userSocket;
		foreach ($socketList as $socket) {
			@socket_write($socket,'hai',strlen('hai'));
		}
	}
	
	//生成唯一的key 用于单用户通信
	
	public function generateRangNum() {
		return md5(time() . mt_rand(1,1000000));
	}
	
}

$s = new SocketServer();
$s -> runStart();

Telnet进行测试配合工具


测试方式 telnet 127.0.0.1 9337端口进行链接  多复制几个shell终端  直接发送信息不要json  这就是全部的

sokit.exe下载该工具,进行链接测试  发送json数据 格式为{"type":"one","userkey":"链接成功服务器返回的id记得保留下来","info":"对单个用户发送的信息"}

ok 你发现你可以通信了,当然你可以自己编写socket进行链接,不过这都不是我的事了。

谢谢你能看完整个教程 


个人随笔

安静的等待,你若盛开,蝴蝶自来

承接高质量 网站开发 app开发 如有需要请点击About联系

@承鹏辉