Accept 차단 모델은 비교적 오래된 모델이지만 차단/비차단, 잠금, 시간 제한 재전송 등 흥미로운 지식이 많이 포함되어 있습니다.
서버 프로그램 acceptSever.php
<?php set_time_limit(0); # 设置脚本执行时间无限制 class SocketServer { private static $socket; function SocketServer($port) { global $errno, $errstr; if ($port < 1024) { die("Port must be a number which bigger than 1024/n"); } $socket = stream_socket_server("tcp://0.0.0.0:{$port}", $errno, $errstr); if (!$socket) die("$errstr ($errno)"); while ($conn = stream_socket_accept($socket, -1)) { // 这样设置不超时才有用 static $id = 0; # 进程 id static $ct = 0; # 接收数据的长度 $ct_last = $ct; $ct_data = ''; # 接受的数据 $buffer = ''; # 分段读取数据 $id++; echo "Client $id come" . PHP_EOL; # 持续监听 while (!preg_match('{/r/n}', $buffer)) { // 没有读到结束符,继续读 // if (feof($conn)) break; // 防止 popen 和 fread 的 bug 导致的死循环 $buffer = fread($conn, 1024); echo 'R' . PHP_EOL; # 打印读的次数 $ct += strlen($buffer); $ct_data .= preg_replace('{/r/n}', '', $buffer); } $ct_size = ($ct - $ct_last) * 8; echo "[$id] " . __METHOD__ . " > " . $ct_data . PHP_EOL; fwrite($conn, "Received $ct_size byte data./r/n"); fclose($conn); } fclose($socket); } } new SocketServer(2000);
클라이언트 프로그램 acceptClient. php
<?php # 日志记录 function debug ($msg) { error_log($msg, 3, './socket.log'); } if ($argv[1]) { $socket_client = stream_socket_client('tcp://0.0.0.0:2000', $errno, $errstr, 30); /* 设置脚本为非阻塞 */ # stream_set_blocking($socket_client, 0); /* 设置脚本超时时间 */ # stream_set_timeout($socket_client, 0, 100000); if (!$socket_client) { die("$errstr ($errno)"); } else { # 填充容器 $msg = trim($argv[1]); for ($i = 0; $i < 10; $i++) { $res = fwrite($socket_client, "$msg($i)"); usleep(100000); echo 'W'; // 打印写的次数 # debug(fread($socket_client, 1024)); // 将产生死锁,因为 fread 在阻塞模式下未读到数据时将等待 } fwrite($socket_client, "/r/n"); // 传输结束符 # 记录日志 debug(fread($socket_client, 1024)); fclose($socket_client); } } else { // $phArr = array(); // for ($i = 0; $i < 10; $i++) { // $phArr[$i] = popen("php ".__FILE__." '{$i}:test'", 'r'); // } // foreach ($phArr as $ph) { // pclose($ph); // } for ($i = 0; $i < 10; $i++) { system("php ".__FILE__." '{$i}:test'"); # 这里等于 php "当前文件" "脚本参数" } }
코드 분석
먼저 위의 코드 논리를 설명하세요. 클라이언트 acceptClient.php는 루프에서 데이터를 보내고 마지막으로 서버에 종료자를 보냅니다. Accept Server.php는 수락 차단 방법을 사용하여 소켓 연결을 받습니다. 그런 다음 종료자가 수신될 때까지 수신 데이터를 반복하고 결과 데이터(수신된 바이트 수)를 반환합니다. 클라이언트는 서버에서 반환된 데이터를 수신하여 로그에 기록합니다. 논리는 매우 간단하지만 분석할 가치가 있는 몇 가지 상황이 있습니다.
A> 기본적으로 php 소켓_client.php 테스트를 실행할 때 클라이언트는 10W를 인쇄하고 서버는 여러 R을 인쇄한 다음 수신된 데이터를 인쇄합니다. 소켓.log는 서버가 반환한 수신 결과 데이터를 기록하며, 그 효과는 다음과 같습니다.
이 상황은 이해하기 쉬우므로 자세히 설명하지 않습니다. 그런 다음 telnet 명령을 사용하여 동시에 여러 클라이언트를 엽니다. 그림에 표시된 대로 서버는 한 번에 하나의 클라이언트만 처리합니다.
다른 클라이언트는 이 뒤에 "대기"해야 합니다. IO를 차단하는 특성이 있습니다. 이 모델의 약점은 명백하며 효율성이 매우 낮습니다.
B> 소켓_client.php의 29번째 줄에 있는 주석 코드만 열고 php 소켓_client.php 테스트를 다시 실행하세요. 클라이언트는 W를 출력하고 서버도 R을 출력합니다. 그 후 두 프로그램 모두 중단됩니다. 그 이유는 논리를 분석한 후에 클라이언트가 종결자를 보내기 전에 서버에 데이터를 반환하기를 원하고 서버가 종결자를 수신하지 않았기 때문에 클라이언트에게도 종결자를 요청하기 때문이라는 것을 알 수 있습니다. 교착 상태를 유발합니다. W와 R 하나만 입력하는 이유는 fread가 기본적으로 차단되기 때문입니다. 이 교착 상태를 해결하려면 소켓_client.php의 17번째 줄에서 주석 코드를 열고 소켓에 대해 timeout을 0.1초로 설정해야 합니다. 다시 실행하면 W와 R이 0.1초마다 나타나는 것을 볼 수 있습니다. 그러면 정상적으로 종료되고 서버는 반환합니다. 수신 결과 데이터도 정상적으로 기록됩니다. fread가 기본적으로 차단되는 것을 볼 수 있습니다. 프로그래밍 시 특별한 주의가 필요합니다. 시간 초과가 설정되지 않으면 교착 상태가 쉽게 발생합니다.
C> 14줄의 주석만 열고 스크립트를 비차단으로 설정합니다. php 소켓_client.php 테스트를 실행합니다. 결과는 기본적으로 사례 A와 동일합니다. 유일한 차이점은 소켓.log가 반환을 기록하지 않는다는 것입니다. non-blocking을 실행하면 클라이언트가 서버의 응답 결과를 기다리지 않고 실행을 계속할 수 있기 때문입니다. 디버그가 실행될 때 읽기 데이터는 여전히 비어 있으므로 소켓.log도 비어 있습니다. 여기서는 차단 모드와 비차단 모드에서 실행되는 클라이언트의 차이점을 볼 수 있습니다. 물론 클라이언트가 결과 수락에 관심이 없는 경우 비차단 모드를 사용하여 최대 효율성을 얻을 수 있습니다.
D> php 소켓_client.php를 실행하면 위의 로직을 10번 연속으로 실행하게 됩니다. 여기에는 아무런 문제가 없지만 매우 이상한 점은 39-45줄의 코드를 사용하고 10개의 프로세스를 열면 된다는 것입니다. 동시에 서버 측의 무한 루프가 매우 이상해집니다! 나중에 조사 결과, popen으로 열린 프로세스에 의해 생성된 연결로 인해 fread 또는 소켓_read가 오류를 일으키고 빈 문자열을 직접 반환하여 무한 루프가 발생하는 한, PHP 소스 코드를 확인한 후 발견되었습니다. PHP의 popen 및 fread 함수는 C에 전혀 고유하지 않은 것으로 나타났으며, 여기에는 많은 양의 php_stream_* 구현 논리가 삽입되어 있으며 이는 내부 버그로 인한 소켓 연결 중단으로 인해 발생하는 것으로 추정됩니다. 해결 방법은 Socket_server.php에서 33줄의 코드를 여는 것입니다. 연결이 중단되면 루프에서 빠져나오지만 이렇게 하면 많은 데이터가 손실되므로 이 문제는 특별한 주의가 필요합니다!
관련 권장 사항:
PHP 정규 표현식이란 무엇입니까? PHP 정규식 사용 방법(코드 포함)
위 내용은 PHP 네트워크 프로그래밍의 차단 모델 허용 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

로드 밸런싱은 세션 관리에 영향을 미치지 만 세션 복제, 세션 끈적임 및 중앙 집중식 세션 스토리지로 해결할 수 있습니다. 1. 세션 복제 복사 서버 간의 세션 데이터. 2. 세션 끈은 사용자 요청을 동일한 서버로 안내합니다. 3. 중앙 집중식 세션 스토리지는 Redis와 같은 독립 서버를 사용하여 세션 데이터를 저장하여 데이터 공유를 보장합니다.

SessionLockingIsateChniqueSureDureauser의 SessionLockingSsessionRemainSexclusivetoOneuseratatime.itiscrucialforpreptingdatacorruptionandsecurityBreachesInmulti-userApplications.sessionLockingSogingSompletEdusingserVerver-sidelockingMegynisms, unrasprantlockinj

PHP 세션의 대안에는 쿠키, 토큰 기반 인증, 데이터베이스 기반 세션 및 Redis/Memcached가 포함됩니다. 1. Cookies는 클라이언트에 데이터를 저장하여 세션을 관리합니다. 이는 단순하지만 보안이 적습니다. 2. Token 기반 인증은 토큰을 사용하여 사용자를 확인합니다. 이는 매우 안전하지만 추가 논리가 필요합니다. 3. Database 기반 세션은 데이터베이스에 데이터를 저장하여 확장 성이 좋지만 성능에 영향을 줄 수 있습니다. 4. Redis/Memcached는 분산 캐시를 사용하여 성능 및 확장 성을 향상하지만 추가 일치가 필요합니다.

SessionHijacking은 사용자의 SessionID를 얻음으로써 사용자를 가장하는 공격자를 말합니다. 예방 방법은 다음과 같습니다. 1) HTTPS를 사용한 의사 소통 암호화; 2) SessionID의 출처를 확인; 3) 보안 세션 생성 알고리즘 사용; 4) 정기적으로 SessionID를 업데이트합니다.

이 기사는 PHP에 대해 설명하고, 전체 형식, 웹 개발의 주요 용도, Python 및 Java와의 비교 및 초보자를위한 학습 용이성을 자세히 설명합니다.

PHP는 유효성 검사, 소독 및 보안 데이터베이스 상호 작용을 통해 보안을 보장하면서 $ \ _ post 및 $ \ _를 사용하여 데이터 양식 데이터를 처리합니다.

이 기사는 PHP와 ASP.NET을 비교하여 대규모 웹 응용 프로그램, 성능 차이 및 보안 기능에 대한 적합성에 중점을 둡니다. 둘 다 대규모 프로젝트에서는 실용적이지만 PHP는 오픈 소스 및 플랫폼 독립적이며 ASP.NET,

PHP의 사례 감도는 다양합니다. 함수는 무감각하고 변수와 클래스는 민감합니다. 모범 사례에는 일관된 이름 지정 및 비교를위한 사례 감수 기능 사용이 포함됩니다.


핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

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

Eclipse용 SAP NetWeaver 서버 어댑터
Eclipse를 SAP NetWeaver 애플리케이션 서버와 통합합니다.

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전
