很多站长朋友们都不太清楚phptcp并发,今天小编就来给大家整理phptcp并发,希望对各位有所帮助,具体内容如下:
本文目录一览: 1、 修改TCP/IP并发连接数 2、 php如何实现websocket 3、 nginx和php的两种通信方式 4、 php为什么要用swoole 5、 SP2的TCP/IP并发连接数是什么?我应该怎样修改它的数值呢? 6、 php swoole 并发多少 修改TCP/IP并发连接数1、可使用以下命令,查看当前服务器启动的httpd进程数,亦即当前服务器提供httpd服务的并发请求数。
2、获取服务器实时的httpd服务并发请求数,可以与配置文件/etc/httpd/conf/httpd.conf中的MaxRequestWorkers 数量进行对比,看是否需要对最大服务并发数进行更改。
3、运行以下命令,则可以对当前服务器为提供web服务,而开放80端口,与外部请求建立连接的连接数进行查看和统计。
4、当前服务器的httpd服务已建立连接数,即httpd服务的TCP连接状态为ESTABLISH的连接,所以可以用以下命令查看、统计。
5、通过查看当前httpd服务的TCP连接数,可对请求访问的IP进行分类汇总,查看是否存在同一IP地址恶意刷连接,过多占用系统资源情况存在,进而做出必要的处理。查看统计命令如下。
6、如果某个IP地址的连接请求过多,我们则可以通过修改配置文件/etc/httpd/conf/httpd.conf,加入以下语句来阻止它的访问。
php如何实现websocketphp有可用的websocket库,不需要php-fpm。
目前比较成熟的有swoole(swoole测试数据),和workman(workman.net)
swoole是c写的php扩展, 效率比nodejs还要高,workman是纯php实现,两者都号称可以实现并发百万TCP连接。
给你个例子:
这个要通过cmd运行的?具体带的参数有点忘记了
<?php
????error_reporting(E_ALL);
????set_time_limit(0);
????ob_implicit_flush();
????//创建一个socket连接?设置参数?绑定?监听?并且返回
????$master??=?WebSocket("localhost",12345);
????//标示是否已经进行过握手了
????$is_shaked?=?false;
????//是否已经关闭
????$is_closed?=?true;
????//将socket变为一个可用的socket
????while(true){
????????//如果是关闭状态并且是没有握手的话?则创建一个可用的socket(貌似第二个条件可以去除)
????????if($is_closed??!$is_shaked){
????????????if(($sock?=?socket_accept($master))?<?0){
????????????????echo?"socket_accept()?failed:?reason:?"?.?socket_strerror($sock)?.?"\n";
????????????}
????????????//将关闭状态修改为false
????????????$is_closed?=?false;
????????}
????????//开始进行数据处理
????????process($sock);
????}
????//处理请求的函数
????function?process($socket){
????????//先从获取到全局变量
????????global?$is_closed,?$is_shaked;
????????//从socket中获取数据
????????$buffer?=?socket_read($socket,2048);
????????//如果buffer返回值为false并且已经握手的话?则断开连接
????????if(!$buffer??$is_shaked){
????????????disconnect($socket);
????????}else{
????????????//如果没有握手的话则握手?并且修改握手状态
????????????if($is_shaked?==?false){
????????????????$return_str?=?dohandshake($buffer);
????????????????$is_shaked?=?true;
????????????}else{
????????????????//如果已经握手的话则送入deal函数中进行相应处理
????????????????$data_str?=?decode($buffer);????//解析出来的从前端送来的内容
????????????????console($data_str);
????????????????$return_str?=?encode(deal($socket,?$data_str));
????????????????//$return_str?=?encode($data_str);
????????????}
????????????//将应该返回的字符串写入socket返回
????????????socket_write($socket,$return_str,strlen($return_str));
????????}
????}
????function?deal($socket,?$msgObj){
????????$obj?=?json_decode($msgObj);
????????foreach($obj?as?$key=>$value){
????????????if($key?==?'close'){
????????????????disconnect($socket);
????????????????console('close?success');
????????????????return?'close?success';
????????????}else?if($key?==?'msg'){
????????????????console($value."\n");
????????????????return?$value;
????????????}
????????}
????}
????//获取头部信息?
????function?getheaders($req){
????????$r=$h=$o=null;
????????if(preg_match("/GET?(.*)?HTTP/"???,$req,$match)){?$r=$match[1];?}
????????if(preg_match("/Host:?(.*)\r\n/"??,$req,$match)){?$h=$match[1];?}
????????if(preg_match("/Origin:?(.*)\r\n/",$req,$match)){?$o=$match[1];?}
????????if(preg_match("/Sec-WebSocket-Key:?(.*)\r\n/",$req,$match)){?$key=$match[1];?}
????????if(preg_match("/\r\n(.*?)\$/",$req,$match)){?$data=$match[1];?}
????????return?array($r,$h,$o,$key,$data);
????}
????function?WebSocket($address,$port){
????????$master=socket_create(AF_INET,?SOCK_STREAM,?SOL_TCP)?????or?die("socket_create()?failed");
????????socket_set_option($master,?SOL_SOCKET,?SO_REUSEADDR,?1)??or?die("socket_option()?failed");
????????socket_bind($master,?$address,?$port)????????????????????or?die("socket_bind()?failed");
????????socket_listen($master,20)????????????????????????????????or?die("socket_listen()?failed");
????????echo?"Server?Started?:?".date('Y-m-d?H:i:s')."\n";
????????echo?"Master?socket??:?".$master."\n";
????????echo?"Listening?on???:?".$address."?port?".$port."\n\n";
????????return?$master;
????}
????function?dohandshake($buffer){
????????list($resource,$host,$origin,$key,$data)?=?getheaders($buffer);
????????echo?"resource?is?$resource\n";
????????echo?"origin?is?$origin\n";
????????echo?"host?is?$host\n";
????????echo?"key?is?$key\n\n";
????????$response_key?=?base64_encode(sha1($key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11',?true));
????????$return_str?=?"HTTP/1.1?101?Switching?Protocols\r\n".
????????????????????"Upgrade:?websocket\r\n".
????????????????????"Connection:?Upgrade\r\n".
????????????????????"Sec-WebSocket-Accept:?$response_key\r\n\r\n";
????????return?$return_str;
????}
????function?console($msg){
????????$msg?=?transToGBK($msg);
????????echo?"$msg\n";
????????return?$msg;
????}
????function?decode($msg="")?{
????????$mask?=?array();
????????$data?=?"";
????????$msg?=?unpack("H*",$msg);
????????$head?=?substr($msg[1],0,2);
????????if?(hexdec($head{1})?===?8){
????????????$data?=?false;
????????}?else?if?(hexdec($head{1})?===?1){
????????????$mask[]?=?hexdec(substr($msg[1],4,2));
????????????$mask[]?=?hexdec(substr($msg[1],6,2));
????????????$mask[]?=?hexdec(substr($msg[1],8,2));
????????????$mask[]?=?hexdec(substr($msg[1],10,2));
????????????$s?=?12;
????????????$e?=?strlen($msg[1])-2;
????????????$n?=?0;
????????????for?($i=?$s;?$i<=?$e;?$i+=?2){
????????????????$data?.=?chr($mask[$n%4]^hexdec(substr($msg[1],$i,2)));
????????????????$n++;
????????????}??
????????}??
????????return?$data;
????}
????function?encode($msg=""){
????????$frame?=?array();
????????$frame[0]?=?"81";
????????$msg?.=?'?is?ok';
????????$len?=?strlen($msg);
????????$frame[1]?=?$len<16?"0".dechex($len):dechex($len);
????????$frame[2]?=?ord_hex($msg);
????????$data?=?implode("",$frame);
????????return?pack("H*",?$data);
????}
????function?transToGBK($s){//UTF8->GBK
????????//echo?$s;
????????return?iconv("UTF-8",?"GBK",?$s);
????????return?$s;
????}
????function?ord_hex($data){
????????$msg?=?"";
????????$l?=?strlen($data);
????????for?($i=0;?$i<$l;?$i++){
????????????//ord是返回字符串第一个字符的ascii值
????????????//dechex把十进制转换为十六进制
????????????$msg?.=?dechex(ord($data{$i}));
????????}
????????return?$msg;
????}
????function?disconnect($socket){
????????global?$is_shaked,?$is_closed;
????????$is_shaked?=?false;
????????$is_closed?=?true;
????????socket_close($socket);
????}
?>
nginx和php的两种通信方式Nginx与PHP的两种通信方式-unix socket和tcp socket
1、两者Nginx配置
unix socket
需要在nginx配置文件中填写php-fpm运行的pid文件地址。
location ~ \.php$ {
? ? include fastcgi_params;
? ? fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;;
? ? fastcgi_pass unix:/var/run/php5-fpm.sock;
? ? fastcgi_index index.php;
}
tcp socket
需要在nginx配置文件中填写php-fpm运行的ip地址和端口号。
location ~ \.php$ {
? ? include fastcgi_params;
? ? fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;;
? ? fastcgi_pass 127.0.0.1:9000;
? ? fastcgi_index index.php;
}
2、两者比较
从上面的图片可以看,unix socket减少了不必要的tcp开销,而tcp需要经过loopback,还要申请临时端口和tcp相关资源。但是,unix socket高并发时候不稳定,连接数爆发时,会产生大量的长时缓存,在没有面向连接协议的支撑下,大数据包可能会直接出错不返回异常。tcp这样的面向连接的协议,多少可以保证通信的正确性和完整性。
3、选择建议:如果是在同一台服务器上运行的nginx和php-fpm,并发量不超过1000,选择unix socket,因为是本地,可以避免一些检查操作(路由等),因此更快,更轻。 如果面临高并发业务,我会选择使用更可靠的tcp socket,以负载均衡、内核优化等运维手段维持效率。
php为什么要用swooleSwoole 使 PHP 开发人员可以编写高性能高并发的 TCP、UDP、Unix Socket、HTTP、 WebSocket 等服务,让 PHP 不再局限于 Web 领域。Swoole4 协程的成熟将 PHP 带入了前所未有的时期, 为性能的提升提供了独一无二的可能性。Swoole 可以广泛应用于互联网、移动通信、云计算、 网络游戏、物联网(IOT)、车联网、智能家居等领域。使用 PHP + Swoole 可以使企业 IT 研发团队的效率大大提升,更加专注于开发创新产品。
SP2的TCP/IP并发连接数是什么?我应该怎样修改它的数值呢?众所周知,为了防范蠕虫病毒的传播和攻击,Windows XP SP2将并发线程最多限制为10个。SP2利用Messages动态链接库,来实时监控每个进程的并发线程数目,一旦它发现某进程的线程数超过10个,就会屏蔽掉部分线程。SP2这样做,虽然可以防范震荡波类型的蠕虫病毒,加强系统安全,但是也带了一些负面影响,例如当你使用BT、P2P或FlashGet软件下载时,部分线程将被屏蔽掉,因此下载速度会变得很慢。为此,你可以采取以下对策,来突破TCP并发连接数,从而提高SP2的多线程访问速度。
一、注册表修改法的误区
为了突破SP2对TCP并发连接数的限制,网上曾经流传过一种修改注册表的方法,操作步骤如下:
单击“开始”/运行,输入Regedit打开注册表,定位到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters下,修改的“TcpNumConnections”的键值,将之由10改为150,即设置TCP最大并发连接数为150。
经过实际测试,我们发现该方法看起来有效,但实质上并不能突破并发连接数限制,提高SP2的多线程访问速度。因为SP2对线程数目的控制,是通过“Tcpip.sys”这个系统文件来实现的,并不是通过注册表实现的,因此,该方法不能增加SP2的TCP并发连接数。
二、使用工具来替换Tcpip.sys
为了突破SP2的TCP并发连接数限制,正确地方法是修改Windows XP SP2的系统文件Tcpip.sys。Tcpip.sys是Windows XP SP2重要的系统文件,位于“C:\Windows\system32\drivers目录下。该文件由于平时受到系统保护,所以正常情况下你是无法替换它的,必须在安全模式或纯DOS模式下才能替换,建议你使用以下专门工具、来替换“Tcpip.sys”文件,操作步骤如下:
从网上下载替换工具(仅为30KB),用它来修改系统文件Tcpip.sys最大安全并发连接限制;然后备份一下C:\Windows\system32\drivers\Tcpip.sys文件。
接下来,双击打开下载文件ZIP压缩包,运行其中的替换工具EvID4226Patch.exe,随之将弹出一个命令行提示符窗口,首先显示Windows当前的Tcpip.sys文件版本,以及并发连接的限制数值(默认为10);接着询问你是否将连接数限制在50(如下图1),你可以选择“Yes/No/Change”,如果你输入“Y”,则会将并发连接数改为“50”,如果想改为其他数(例如150),可以在提示符后输入“c”,然后输入最大的并发连接数(例如150)回车,最后在提示符下输入“Y”并回车,这样就替换了Tcpip.sys文件;Tcpip.sys文件被替换后,随之会弹出系统文件保护对话框,你可以点击“取消”按钮,然后点击“是”按钮,重新启动后,Tcpip.sys文件的替换就大功告成了!
现在你的最大并发连接数已超过10个,达到了150个,因此Windows XP SP2的多线程访问速度得到了提升,当你用FlashGet、BT等多线程下载时,就不会感到网络带宽的限制了。
三、DOS下修改Tcpip.sys文件
以上替换程序EvID4226Patch.exe也可以在DOS下使用,方法是:首先把EvID4226Patch.exe拷贝到C盘根目录下;然后再进入DOS模式,进入C盘根目录,输入命令EvID4226Patch/L=$n$/w=C:\WINDOWS\system32\drivers/L=tcpip.sys即可修改Tcpip.sys文件。
注意:以上$n$为你要设置的最大安全连接数,假如要把最大并发连接数设置为150个线程,那么输入命令EvID4226Patch/L=150/w=C:\WINDOWS\system32\drivers/L=tcpip.sys即可。
四、使用比特精灵附带的工具
比特精灵附带的工具“TCP/IP连接数破解补丁”也可以替换Tcpip.sys,突破SP2的TCP并发连接数限制。
从网上下载比特精灵(BitSpirit)V2.7.2.225简体中文正式版,然后双击下载文件进行安装。你可以选择安装哪些组件(下图2),应该安装“用于Windows XP SP2的TCP/IP连接数破解补丁”,安装结束后,XP开始菜单中就会有BitSpirit程序组,单击其中的“XP SP2连接数破解补丁”,即可修改Tcpip.sys文件。
单击“XP SP2连接数破解补丁”,弹出该软件的界面,界面中列出了当前Tcpip.sys的版本、及最大并发连接数(右图3),你可以在“TCP/IP Linitation”输入一个数,来设置最大并发连接数,例如输入150,然后按“Apply”按钮,重启系统后,你的SP2最大并发连接数就改为了150。
以上几种方法虽然提高了Windows XP SP2的多线程访问速度,但却降低了SP2的安全性能,如果你的电脑感染了病毒和木马,过多地启用新线程,会加速病毒和木马地蔓延,因此你在追求网络下载速度的同时,也要注意网络安全。建议你及时安装升级杀毒软件和防火墙,如果是普通用户,可以利用上面的方法,将TCP最大并发连接数设置为10~30,BT用户可以设置为100~150。
参考资料:
php swoole 并发多少HttpServer
$serv = new Swoole\Http\Server("127.0.0.1", 9502);
$serv->on('Request', function($request, $response) {
var_dump($request->get);
var_dump($request->post);
var_dump($request->cookie);
var_dump($request->files);
var_dump($request->header);
var_dump($request->server);
$response->cookie("User", "Swoole");
$response->header("X-Server", "Swoole");
$response->end("<h1>Hello Swoole!</h1>");
});
$serv->start();
WebSocket Server
$serv = new Swoole\Websocket\Server("127.0.0.1", 9502);
$serv->on('Open', function($server, $req) {
echo "connection open: ".$req->fd;
});
$serv->on('Message', function($server, $frame) {
echo "message: ".$frame->data;
$server->push($frame->fd, json_encode(["hello", "world"]));
});
$serv->on('Close', function($server, $fd) {
echo "connection close: ".$fd;
});
$serv->start();
TCP Server
$serv = new Swoole\Server("127.0.0.1", 9501);
$serv->set(array(
'worker_num' => 8, //工作进程数量
'daemonize' => true, //是否作为守护进程
));
$serv->on('connect', function ($serv, $fd){
echo "Client:Connect.\n";
});
$serv->on('receive', function ($serv, $fd, $from_id, $data) {
$serv->send($fd, 'Swoole: '.$data);
$serv->close($fd);
});
$serv->on('close', function ($serv, $fd) {
echo "Client: Close.\n";
});
$serv->start();
TCP Client
$client = new Swoole\Client(SWOOLE_SOCK_TCP, SWOOLE_SOCK_ASYNC);
//设置事件回调函数
$client->on("connect", function($cli) {
$cli->send("hello world\n");
});
$client->on("receive", function($cli, $data){
echo "Received: ".$data."\n";
});
$client->on("error", function($cli){
echo "Connect failed\n";
});
$client->on("close", function($cli){
echo "Connection close\n";
});
//发起网络连接
$client->connect('127.0.0.1', 9501, 0.5);
异步MySQL
$db = new Swoole\MySQL;
$server = array(
'host' => '127.0.0.1',
'user' => 'test',
'password' => 'test',
'database' => 'test',
);
$db->connect($server, function ($db, $result) {
$db->query("show tables", function (Swoole\MySQL $db, $result) {
if ($result === false) {
var_dump($db->error, $db->errno);
} elseif ($result === true) {
var_dump($db->affected_rows, $db->insert_id);
} else {
var_dump($result);
$db->close();
}
});
});
异步Redis/异步Http客户端
$redis = new Swoole\Redis;
$redis->connect('127.0.0.1', 6379, function ($redis, $result) {
$redis->set('test_key', 'value', function ($redis, $result) {
$redis->get('test_key', function ($redis, $result) {
var_dump($result);
});
});
});
$cli = new Swoole\Http\Client('127.0.0.1', 80);
$cli->setHeaders(array('User-Agent' => 'swoole-http-client'));
$cli->setCookies(array('test' => 'value'));
$cli->post('/dump.php', array("test" => 'abc'), function ($cli) {
var_dump($cli->body);
$cli->get('/index.php', function ($cli) {
var_dump($cli->cookies);
var_dump($cli->headers);
});
});
Async-IO
$fp = stream_socket_client("tcp://127.0.0.1:80", $code, $msg, 3);
$http_request = "GET /index.html HTTP/1.1\r\n\r\n";
fwrite($fp, $http_request);
Swoole\Event::add($fp, function($fp){
echo fread($fp, 8192);
swoole_event_del($fp);
fclose($fp);
});
Swoole\Timer::after(2000, function() {
echo "2000ms timeout\n";
});
Swoole\Timer::tick(1000, function() {
echo "1000ms interval\n";
});
异步任务
$serv = new Swoole\Server("127.0.0.1", 9502);
$serv->set(array('task_worker_num' => 4));
$serv->on('Receive', function($serv, $fd, $from_id, $data) {
$task_id = $serv->task("Async");
echo "Dispath AsyncTask: id=$task_id\n";
});
$serv->on('Task', function ($serv, $task_id, $from_id, $data) {
echo "New AsyncTask[id=$task_id]".PHP_EOL;
$serv->finish("$data -> OK");
});
$serv->on('Finish', function ($serv, $task_id, $data) {
echo "AsyncTask[$task_id] Finish: $data".PHP_EOL;
});
$serv->start();
关于phptcp并发的介绍到此就结束了,不知道本篇文章是否对您有帮助呢?如果你还想了解更多此类信息,记得收藏关注本站,我们会不定期更新哦。
查看更多关于phptcp并发 php如何处理并发请求的详细内容...