socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。 详情>>
要想客户端能通过websocket来访问,就必须先开启一个服务端的socket进程,来接收数据。
服务器端:
<?php //创建一个套接字 echo:resource(4) of type (Socket) $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //套接字端口被释放后可以立即被使用,无须等待。 socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, true); //给套接字绑定名字,将套接字与特定的IP地址和端口绑定起来 socket_bind($socket,'0.0.0.0',8888); //让套接字进入被动监听状态 socket_listen($socket); $sockets[] = $socket; $write = NUll; $except = NUll; while(true){ //$tmp_socket 里存放着所有链接着的客户端和服务器的 套接字。 $tmp_socket = $sockets; var_dump($tmp_socket); var_dump($sockets); //socket_select()是用来堵塞的,判断有没有客户端连接,或者客户端发送数据。 //或者数组里存在 不存在的 套接字 。比如说我又 2个链接,加上我自己应该是3个套接字,但是有一个断开了链接, //那就应该是还剩2个套接字,但我们并没有删除数组中这个套接字,就会出现这种情况,导致socket_select()无限次被触发。 //情况一:新客户端连接,$tmp_socket就会被只剩余$socket,也就是服务器创建的套接字, //情况二:客户端发送数据:$tmp_socket就会只剩余 客户端的套接字,谁发送了就变为谁。 //切记:$tmp_socket最终返回的是一个有下标的数组,这个下标是未修改前的下标,这也是为什么要是用sort()来排序一下。 //注意:$tmp_socket 和 $write 和 $except 都是引用传值。你可以去查看一下手册。 socket_select($tmp_socket, $write, $except, NUll); var_dump($tmp_socket); //这里的sort并不是为了排序,而是为了干掉他的默认下标。 sort($tmp_socket); if ($tmp_socket[0] == $socket) { //接收客户端请求,返回一个新的套接字来和客户端通信, //后面和客户端通信时,要使用这个新生成的套接字,而不是原来服务器端的套接字。 // socket_accept()会在服务器中产生一个 0.0.0.0:8888的进程等待客户端连接,并堵塞代码的执行。这里的ip:port是上面指定的。 //一但有客户端连接成功就会继续执行。 $client = socket_accept($socket); $sockets[] = $client; var_dump($sockets); }else{ //从客户端的套接字中读取数据 $reMsg = socket_read($tmp_socket[0],1024); //向客户端的套接字中写入数据 socket_write($tmp_socket[0],$reMsg,strlen($reMsg)); echo $reMsg; } };
客户端
<?php $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //连接一个socket socket_connect($socket, '127.0.0.1',8888); $str = 'this is client'.PHP_EOL; while (true) { //在命令行下可以输出内容 fwrite(STDOUT, '请输入内容:'); //在命令行下可以输入内容 $str = fgets(STDIN); //向套接字中写入数据 socket_write($socket, $str, strlen($str)); //从套接字中读取数据 echo socket_read($socket , 1024); }