백엔드 개발 PHP 튜토리얼 php fsockopen解决方法

php fsockopen解决方法

Jun 13, 2016 am 10:39 AM
host socket sockets stream

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。

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Windows 11 종료 프롬프트 작업 호스트 창 작업 호스트가 종료 작업 솔루션을 실행 중입니다. Windows 11 종료 프롬프트 작업 호스트 창 작업 호스트가 종료 작업 솔루션을 실행 중입니다. Feb 12, 2024 pm 12:40 PM

최근 많은 Win11 사용자가 종료할 때 taskhostwindow 작업 호스트가 종료 작업을 실행하고 있다는 메시지가 표시된다고 보고했습니다. 무슨 일이 일어나고 있는 걸까요? 사용자는 로컬 레지스트리 편집기 아래 Desktop 폴더에 들어간 후 오른쪽 창에서 AutoEndTasks를 선택하여 설정할 수 있습니다. 이 사이트를 종료할 때 이 문제에 대한 해결책을 사용자에게 주의 깊게 소개하십시오. Windows 11 종료에서는 taskhostwindow 작업 호스트가 종료 작업을 실행 중이라는 메시지가 표시됩니다. 해결 방법 1. 아래 그림과 같이 win 키 + r 키 조합을 사용하여 "regedit"를 입력하고 Enter 키를 누릅니다. 2. [HKEY]를 검색하세요

Windows 11에서 Aggregator host.exe가 안전한지 확인하는 방법 Windows 11에서 Aggregator host.exe가 안전한지 확인하는 방법 Apr 13, 2023 pm 04:22 PM

작업을 종료하거나 응용 프로그램을 중지하기 위해 작업 관리자를 시작할 때 일반적으로 많은 수의 프로세스가 실행되고 있는 것을 발견합니다. 이것은 완전히 정상입니다. 그러나 때로는 우리가 전혀 인식하지 못하는 시스템 리소스를 사용하는 프로그램을 볼 수 있습니다. 이러한 프로세스 중 하나는 최근 사용자들 사이에 혼란을 야기하고 있는 수집기 호스트.exe입니다. 이러한 프로세스 중 일부는 합법적인 Windows 요구 사항일 수 있지만 다른 프로세스는 백그라운드에서 실행되어 사용자가 알지 못하거나 동의하지 않고 문제를 일으키는 악성 프로그램일 수 있습니다. Windows 11에서 작업 관리자를 시작할 수 있는 5가지 방법을 살펴본 후 aggregator host.exe가 안전한지 또는 바이러스인지 확인하는 방법을 보여 드리겠습니다. 유지하다

호스트에 대한 경로가 없는 경우 수행할 작업 호스트에 대한 경로가 없는 경우 수행할 작업 Oct 07, 2023 am 10:50 AM

"호스트에 대한 경로 없음"에 대한 해결 방법에는 네트워크 연결 확인, IP 주소 및 포트 확인, 방화벽 구성 확인, 라우팅 구성 확인, 네트워크 장치 구성 확인, 네트워크 서비스 상태 확인, 네트워크 구성 확인 및 연결이 포함됩니다. 네트워크 관리자. 자세한 소개: 1. 네트워크 연결을 확인하여 클라이언트와 대상 호스트 간의 네트워크 연결이 정상적인지 확인하십시오. ping 명령이나 기타 네트워크 도구를 통해 네트워크 연결을 테스트하고 네트워크 케이블과 같은 하드웨어 장치가 있는지 확인할 수 있습니다. , 무선 네트워크 및 라우터가 제대로 작동하는지 확인하세요. 네트워크 연결이 안정적인지 확인하세요.

마스터와 호스트의 차이점은 무엇입니까 마스터와 호스트의 차이점은 무엇입니까 Sep 28, 2023 pm 01:34 PM

마스터와 호스트의 차이점은 다음과 같습니다. 1. 호스트는 클라이언트 또는 서버 역할을 할 수 있지만 마스터는 분산 시스템에서 다른 슬레이브 서버를 조정하고 관리하는 중앙 서버입니다. 2. 호스트는 일반 컴퓨터 장치이며 마스터입니다. 일반적으로 처리 능력이 더 높으며 작업을 처리 및 분산하고 데이터를 관리하며 전체 시스템의 안정성을 유지하는 데 사용됩니다. 3. 호스트는 네트워크의 노드이고 마스터는 네트워크에서 핵심 역할을 하는 서버입니다. 분산 시스템.

Python의 소켓 및 소켓 서버를 사용하는 방법 Python의 소켓 및 소켓 서버를 사용하는 방법 May 28, 2023 pm 08:10 PM

1. TCP 프로토콜 기반 소켓 프로그래밍 1. 소켓 워크플로는 서버 측에서 시작됩니다. 서버는 먼저 소켓을 초기화한 다음 포트에 바인드하고 포트를 수신하며 차단을 위해 승인을 호출하고 클라이언트가 연결될 때까지 기다립니다. 이때 클라이언트가 Socket을 초기화한 후 서버에 연결(connect)하면, 연결에 성공하면 클라이언트와 서버 간의 연결이 성립된다. 클라이언트는 데이터 요청을 보내고, 서버는 요청을 받아 요청을 처리한 후 클라이언트에 응답 데이터를 보내고, 클라이언트는 데이터를 읽고 마지막으로 연결을 종료합니다. 이를 구현하려면 다음 Python 코드를 사용하세요. : importso

Windows 11에서 WMI 공급자 호스트 높은 CPU를 수정하는 4가지 빠른 팁 Windows 11에서 WMI 공급자 호스트 높은 CPU를 수정하는 4가지 빠른 팁 Apr 18, 2023 pm 08:25 PM

WMIProviderHost 프로세스는 Windows 11에서 중요한 역할을 합니다. 이를 통해 다른 응용 프로그램이 컴퓨터에 대한 정보를 요청할 수 있습니다. WMIProviderHost와 관련된 프로세스는 일반적으로 백그라운드에서 실행되므로 일반적으로 많은 양의 시스템 리소스를 소비하지 않습니다. 하지만 이 서비스는 다른 애플리케이션으로 인해 때때로 CPU 성능의 50% 이상을 사용하는 것으로 알려졌습니다. 장시간 동안 컴퓨터 프로세서를 거의 최대 용량으로 실행하는 것은 걱정스러운 일입니다. 그렇게 하면 시스템 구성 요소가 과열되거나 손상될 수 있습니다. 오늘의 튜토리얼에서는 WMIProviderHost가 Windows 11의 C에서 작동하는 이유를 살펴보겠습니다.

PHP+Socket 시리즈의 IO 다중화 및 웹서버 구현 PHP+Socket 시리즈의 IO 다중화 및 웹서버 구현 Feb 02, 2023 pm 01:43 PM

이 기사에서는 주로 IO 멀티플렉싱을 소개하는 php+socket과 php+socket이 웹 서버를 구현하는 방법에 대한 관련 지식을 제공합니다. 관심 있는 친구들은 아래를 살펴보시면 모두에게 도움이 되길 바랍니다.

Spring Boot+Vue를 사용하여 소켓 알림 푸시를 구현하는 방법 Spring Boot+Vue를 사용하여 소켓 알림 푸시를 구현하는 방법 May 27, 2023 am 08:47 AM

SpringBoot 측의 첫 번째 단계는 종속성을 도입하는 것입니다. 먼저 WebSocket에 필요한 종속성과 com.alibabafastjson1.2.73org.springframework.bootspring-boot-starter-websocket 출력 형식을 처리하기 위한 종속성을 도입해야 합니다. 두 번째 단계는 WebSocket 구성 클래스 importorg를 생성하는 것입니다. springframework.context.annotation.Bean;importorg.springframework.context.annotation.Config

See all articles