php socket IO阻塞方式的Server/Client
来源:互联网 发布:香港网络歌手小背心 编辑:程序博客网 时间:2024/06/06 07:16
php的socket编程和java的socket编程区别还是蛮大的,默认情况下php的socket不能像java socket开启多线程来同时接收多个客户端的连接。
使用 telnet 命令同时打开多个客户端测试,你会发现服务器一个时间只处理一个客户端,其他需要在后面“排队”;只有当前的客户端端口才会处理下一个连接
这就是阻塞 IO 的特点,这种模式的弱点很明显,效率极低
网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式
同步、异步和阻塞、非阻塞是组合关系,因此有4种方式:
同步阻塞、同步非阻塞、异步阻塞、异步非阻塞
linux有五种I/O模型
1)阻塞I/O(blocking I/O)
2)非阻塞I/O (nonblocking I/O)
3)I/O复用(select 和poll) (I/O multiplexing)
4)信号驱动I/O (signal driven I/O (SIGIO))
5)异步I/O (asynchronous I/O (the POSIX aio_functions))
前四种都是同步,只有最后一种才是异步IO
详细了解:浅谈socket同步和异步、阻塞和非阻塞、I/O模型_php技巧
client.php
运行效果
使用 telnet 命令同时打开多个客户端测试,你会发现服务器一个时间只处理一个客户端,其他需要在后面“排队”;只有当前的客户端端口才会处理下一个连接
这就是阻塞 IO 的特点,这种模式的弱点很明显,效率极低
网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式
同步、异步和阻塞、非阻塞是组合关系,因此有4种方式:
同步阻塞、同步非阻塞、异步阻塞、异步非阻塞
linux有五种I/O模型
1)阻塞I/O(blocking I/O)
2)非阻塞I/O (nonblocking I/O)
3)I/O复用(select 和poll) (I/O multiplexing)
4)信号驱动I/O (signal driven I/O (SIGIO))
5)异步I/O (asynchronous I/O (the POSIX aio_functions))
前四种都是同步,只有最后一种才是异步IO
详细了解:浅谈socket同步和异步、阻塞和非阻塞、I/O模型_php技巧
以下是php cli模式下阻塞I/O方式的socekt server/client 示例代码
server.php
<?php/** * socket_server.php. * User: lvfk * Date: 2017/11/20 0020 * Time: 17:28 * Desc: php socket server *//*+-------------------------------* @socket通信整个过程+-------------------------------* @socket_create* @socket_bind* @socket_listen* @socket_accept* @socket_read* @socket_write* @socket_close* @socket_strerror* @socket_getpeername+--------------------------------*/set_time_limit(0);//确保连接客户端不会超时$ip = '127.0.0.1';$port = 5555;//创建socketif(($socket = socket_create(AF_INET, STREAM_SOCK_STREAM, SOL_TCP)) < 0){ echo "socket_create() 失败的原因是:".socket_strerror(socket_last_error())."\n";}//阻塞模式socket_set_block($socket) or die("socket_set_block() 失败的原因是:" . socket_strerror(socket_last_error()) . "\n");//绑定ip和端口if(($ret = socket_bind($socket, $ip, $port)) < 0){ echo "socket_bind() 失败的原因是:".socket_strerror($ret)."\n";}//监听if(($ret = socket_listen($socket)) < 0){ echo "socket_listen() 失败的原因是:".socket_strerror($ret)."\n";}echo "PHP Socket Server create suc!\n";$buf = null;do{ // 接受一个Socket客户端连接 if(($client = socket_accept($socket)) < 0){ echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($client)) . "\n"; }else{ socket_getpeername($client, $client_addr, $client_port); //告知客户端连接成功 $msg = "connect suc!"; socket_write($client, $msg, strlen($msg)); do{ //打印客户端发送来的信息 if(($buf = @socket_read($client, 8192)) === false){ echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($client)) . "\n"; socket_close($client); break; } echo "rev client[{$client_addr}]:".$buf."\n"; //服务器发送给客户端 $buf = 'server send:'.$buf; socket_write($client, $buf, strlen($buf)); }while(true); } if('exit' == $buf){ break; }}while(true);//关闭socketsocket_close($socket);
client.php
<?php/** * socket_client.php. * User: lvfk * Date: 2017/11/21 0021 * Time: 9:57 * Desc: php socket client *//*+-------------------------------* @socket通信整个过程+-------------------------------* @socket_create* @socket_connect* @socket_read* @socket_write* @socket_close* @socket_strerror* @socket_getpeername+--------------------------------*/error_reporting(E_ALL);set_time_limit(0);echo "start connect server\n";$ip = '127.0.0.1';$port = 5555;//创建socketif(($socket = socket_create(AF_INET, STREAM_SOCK_STREAM, SOL_TCP)) < 0){ echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";}/***设置socket连接选项,这两个步骤可以省略***///接收套接流的最大超时时间1秒,后面是微秒单位超时时间,设置为零,表示不管它socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array("sec" => 1, "usec" => 0));//发送套接流的最大超时时间为6秒socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array("sec" => 6, "usec" => 0));/***设置socket连接选项,这两个步骤可以省略***/$info = "connect $ip:$port...\n";echo $info;//连接到127.0.0.1:5555这个socket server上面if(($ret = socket_connect($socket, $ip, $port)) < 0){ echo "socket_connect() failed.\nReason: ($ret) " . socket_strerror($ret) . "\n";}do{ //读取服务器发送信息 $out = socket_read($socket, 8192); echo "client rev:",$out."\n"; //读取键盘输入并发送给服务器 $in = trim(fgets(STDIN)); if(! socket_write($socket, $in, strlen($in))){ echo "socket_write() failed: reason: " . socket_strerror(socket_last_error($socket)) . "\n"; } //判断是否退出命令 if('exit' == $in){ echo "client quit\n"; break; }}while(true);//关闭socketsocket_close($socket);
运行效果
Server:
Client1:
可以正常的通信数据
Client2
当Client1继续连接时,Client2会被阻塞
当此时断掉Client1时,Client2就可以正常通信
所以,这种简单的socket通信就是IO阻塞的
阅读全文
0 0
- php socket IO阻塞方式的Server/Client
- socket.io client + socketio-netty server简析
- 构建实时Web的JAVA选择组合:socket.io client + socketio-netty server
- 构建实时Web的JAVA选择组合:socket.io client + socketio-netty server
- Android Java端的Socket.io-client
- 网络编程Socket的阻塞和非阻塞IO
- socket.io client api
- socket.io使用之io.socket.engineio.client.EngineIOException: server error,parser error
- Socket的Server-Client模型的程序
- Java Socket 简单的Client/Server程序
- Java Socket 简单的Client/Server程序
- 简单的socket UDP Client Server通信
- socket通信server+client的C++版
- Java Socket 简单的Client/Server程序
- 使用非阻塞方式的Socket通信
- socket 非阻塞的几种方式
- Socket Server Client Sample
- python socket-server-client
- Leetcode:14. Longest Common Prefix
- 尝试阅读ReentrantLock、AbstractQueuedSynchronizer源码(二)
- RPC入门总结(五)RPC IO基础:Netty高性能并发关键技术点
- Week 1, Aerial Robotics
- Android心跳包(一)——心跳机制
- php socket IO阻塞方式的Server/Client
- 想去阿里巴巴面试么
- Nginx学习-初步理解
- leetcode 173. Binary Search Tree Iterator
- maven私服nexus忘记密码,解决方法(转载)
- NOIP2017过山车记
- 引导滤波的opencv实现以及解释
- 利用SecureCRT上传、下载文件(使用sz与rz命令),超实用!
- 04-树4 是否同一棵二叉搜索树(25 分)---陈越、何钦铭-数据结构-2017秋