php fsockopen解决方法
php fsockopen解决办法
最近研究php多线程的问题,发现中文资源少的可怜,仅有的几篇文章被转了又转,但文中内容价值有限。搜索过程中发现国外很多网站引用的一篇文章写的不错,所以翻译过来。
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
http://blog.iyi.cn/start/
问题:
有没有办法在php中实现多线程呢?
假设你正在写一个基于多台服务器的php应用,理想的情况时同时向多台服务器发送请求,而不是一台接一台。
可以实现吗?
回答:
当有人想要实现并发功能时,他们通常会想到用fork或者spawn threads,但是当他们发现php不支持多线程的时候,大概会转换思路去用一些不够好的语言,比如perl。
其实的是大多数情况下,你大可不必使用fork或者线程,并且你会得到比用fork或thread更好的性能。
假设你要建立一个服务来检查正在运行的n台服务器,以确定他们还在正常运转。你可能会写下面这样的代码:
?
<?php $hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com"); $timeout = 15; $status = array(); foreach ($hosts as $host) { ??? $errno = 0; ??? $errstr = ""; ??? $s = fsockopen($host, 80, $errno, $errstr, $timeout); ??? if ($s) { ??????? $status[$host] = "Connectedn"; ??????? fwrite($s, "HEAD / HTTP/1.0rnHost: $hostrnrn"); ??????? do { ??????????? $data = fread($s, 8192); ??????????? if (strlen($data) == 0) { break; } ? ? ? ? ? ? $status[$host] .= $data; ??????? } while (true); fclose($s); ??? } else { ??????? $status[$host] = "Connection failed: $errno $errstrn"; ??? } } print_r($status); ?>
它运行的很好,但是在fsockopen()分析完hostname并且建立一个成功的连接(或者延时$timeout秒)之前,扩充这段代码来管理大量服务器将耗费很长时间。
因此我们必须放弃这段代码;我们可以建立异步连接-不需要等待fsockopen返回连接状态。PHP仍然需要解析hostname(所以直接使用ip更加明智),不过将在打开一个连接之后立刻返回,继而我们就可以连接下一台服务器。
有两种方法可以实现;PHP5中可以使用新增的stream_socket_client()函数直接替换掉fsocketopen()。PHP5之前的版本,你需要自己动手,用sockets扩展解决问题。
下面是PHP5中的解决方法:
<?php $hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com"); $timeout = 15; $status = array(); $sockets = array(); foreach ($hosts as $id => $host) { ??? $s = stream_socket_client("$host:80", $errno, $errstr, $timeout,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); ??? if ($s) { ??????? $sockets[$id] = $s; ??????? $status[$id] = "in progress"; ??? } else { ??????? $status[$id] = "failed, $errno $errstr"; ??? } } while (count($sockets)) { ??? $read = $write = $sockets; ??? $n = stream_select($read, $write, $e = null, $timeout); ??? if ($n > 0) { ??????? foreach ($read as $r) { ??????????? $id = array_search($r, $sockets); ??????????? $data = fread($r, 8192); ??????????? if (strlen($data) == 0) { ??????????????? if ($status[$id] == "in progress") { ??????????????????? $status[$id] = "failed to connect"; ??????????????? }??????????? ??????????????? fclose($r); ??????????????? unset($sockets[$id]); ??????????? } else { ??????????????? $status[$id] .= $data; ??????????? } ??????? } ??????? foreach ($write as $w) { ??????????? $id = array_search($w, $sockets); ??????????? fwrite($w, "HEAD / HTTP/1.0rnHost: " . $hosts[$id] . "rnrn"); ??????????? $status[$id] = "waiting for response"; ??????? } ??? } else { ??????? foreach ($sockets as $id => $s) { ??????????? $status[$id] = "timed out " . $status[$id]; ??????? } ??????? break; ??? } } foreach ($hosts as $id => $host) { ??? echo "Host: $hostn"; echo "Status: " . $status[$id] . "nn"; } ?>
我们用stream_select()等待sockets打开的连接事件。stream_select()调用系统的select(2)函数来工作:前面三个参数是你要使用的streams的数组;你可以对其读取,写入和获取异常(分别针对三个参数)。stream_select()可以通过设置$timeout(秒)参数来等待事件发生-事件发生时,相应的sockets数据将写入你传入的参数。
下面是PHP4.1.0之后版本的实现,如果你已经在编译PHP时包含了sockets(ext/sockets)支持,你可以使用根上面类似的代码,只是需要将上面的streams/filesystem函数的功能用ext/sockets函数实现。主要的不同在于我们用下面的函数代替 stream_socket_client()来建立连接:
<?php // This value is correct for Linux, other systems have other values define('EINPROGRESS', 115); function non_blocking_connect($host, $port, &$errno, &$errstr, $timeout) { ??? $ip = gethostbyname($host); ??? $s = socket_create(AF_INET, SOCK_STREAM, 0); ??? if (socket_set_nonblock($s)) { ??????? $r = @socket_connect($s, $ip, $port); ??????? if ($r || socket_last_error() == EINPROGRESS) { ??????????? $errno = EINPROGRESS; return $s; ??????? } ??? } ??? $errno = socket_last_error($s); ??? $errstr = socket_strerror($errno); ??? socket_close($s); ??? return false; } ?>
现在用socket_select()替换掉stream_select(),用socket_read()替换掉fread(),用 socket_write()替换掉fwrite(),用socket_close()替换掉fclose()就可以执行脚本了!
PHP5的先进之处在于,你可以用stream_select()处理几乎所有的stream-例如你可以通过include STDIN用它接收键盘输入并保存进数组,你还可以接收通过proc_open()打开的管道中的数据。
如果你想让PHP4.3.x自身拥有处理streams的功能,我已经为你准备了一个让fsockopen可以异步工作的patch。不赞成使用该补丁,该补丁不会出现在官方发布的PHP版本中,我在补丁中附带了stream_socket_client()函数的实现,通过它,你可以让你的脚本兼容 PHP5。

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Recently, many Win11 users have reported that when shutting down, they are prompted that the taskhostwindow task host is executing the shutdown task. So what is going on? Users can enter the Desktop folder under the local registry editor, and then select AutoEndTasks in the right window to set it. Let this site carefully introduce to users the solution to this problem when shutting down. Windows 11 shutdown prompts that the taskhostwindow task host is executing the shutdown task. Solution 1. Use the key combination win key + r key, enter "regedit" and press Enter, as shown in the figure below. 2. Search for [HKEY

When we launch Task Manager to terminate a task or stop an application, we usually find a large number of processes running. This is completely normal. However, sometimes we see programs that are using system resources that we are completely unaware of. One of these processes is the aggregator host.exe, which has been causing some confusion among users recently. Some of these processes may be legitimate Windows requirements, but others may be malicious programs running in the background and causing problems without the user's knowledge or consent. After we've seen the five ways you can launch Task Manager in Windows 11, we'll show you how to check if aggregator host.exe is safe or a virus. keep up

The differences between master and host are: 1. Host can play the role of client or server, while master is the central server responsible for coordinating and managing other slave servers in a distributed system; 2. Host is an ordinary computer device, and master usually has Higher processing power and resources are used to process and distribute tasks, manage data, and maintain the stability of the entire system; 3. The host is a node in the network, and the master is the server that plays a core role in the distributed system.

The solutions to "no route to host" include checking the network connection, checking the IP address and port, checking the firewall configuration, checking the routing configuration, checking the network device configuration, checking the network service status, checking the network configuration and contacting the network administrator. Detailed introduction: 1. Check the network connection to ensure that the network connection between the client and the target host is normal. You can try to test network connectivity through the ping command or other network tools, and check whether hardware devices such as network cables, wireless networks, and routers are working properly. Make sure the network connection is stable, etc.

This article brings you relevant knowledge about php+socket, which mainly introduces IO multiplexing and how php+socket implements web server? Friends who are interested can take a look below. I hope it will be helpful to everyone.

1. Socket programming based on TCP protocol 1. The socket workflow starts with the server side. The server first initializes the Socket, then binds to the port, listens to the port, calls accept to block, and waits for the client to connect. At this time, if a client initializes a Socket and then connects to the server (connect), if the connection is successful, the connection between the client and the server is established. The client sends a data request, the server receives the request and processes the request, then sends the response data to the client, the client reads the data, and finally closes the connection. An interaction ends. Use the following Python code to implement it: importso

The WMIProviderHost process plays a vital role in Windows 11. It enables other applications to request information about your computer. Processes related to WMIProviderHost typically run in the background; therefore, they typically do not consume large amounts of system resources. However, the service reportedly uses more than 50% of CPU power at times due to other applications. It is worrisome to run your computer's processor at nearly maximum capacity for an extended period of time, as this can lead to overheating and damage to system components. In today's tutorial, we will look at why WMIProviderHost works in C on Windows 11

The first step on the SpringBoot side is to introduce dependencies. First we need to introduce the dependencies required for WebSocket, as well as the dependencies for processing the output format com.alibabafastjson1.2.73org.springframework.bootspring-boot-starter-websocket. The second step is to create the WebSocket configuration class importorg. springframework.context.annotation.Bean;importorg.springframework.context.annotation.Config
