PHP에서 GetServbyName (String $ Service, String $ Protocol)은 서비스 이름 (예 : HTTP , SSH ) 및 프로토콜 ( TCP 또는 UDP )에 따라 해당 포트 번호 (소수 정수)를 반환 할 수 있습니다. 서비스 이름을 찾을 수 없거나 오류가 발생하면 함수는 False를 반환합니다. 따라서 시스템 서비스 데이터베이스 (예 : Linux의 /etc /서비스 , Windows 용 서비스 파일 등)에 서비스 이름이 존재하는지 여부를 결정하는 데 사용 할 수 있습니다. 참고 : 이는 서비스가 현재 연결되어 있는지 확인하는지 확인하기보다는 이름이 포트에 매핑되어 있는지 확인하는 것입니다.
다음 예는 실제 사용, 캡슐화 기능, 고려 사항 및 실제 가용성에 대한 추가 감지 방법을 보여줍니다 (서비스가 실제로 연결되어 있는지 확인 해야하는 경우).
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$service</span></span><span> = </span><span><span class="hljs-string">'http'</span></span><span>;
</span><span><span class="hljs-variable">$protocol</span></span><span> = </span><span><span class="hljs-string">'tcp'</span></span><span>;
</span><span><span class="hljs-variable">$port</span></span><span> = </span><span><span class="hljs-title function_ invoke__">getservbyname</span></span><span>(</span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-variable">$protocol</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$port</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"서비스 이름 '<span class="hljs-subst">{$service}</span></span></span><span>'(규약 </span><span><span class="hljs-subst">{$protocol}</span></span><span>)기본 서비스 데이터베이스에는 존재하지 않습니다。\n";
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"제공하다 '<span class="hljs-subst">{$service}</span></span></span><span>'(</span><span><span class="hljs-subst">{$protocol}</span></span><span>)포트에지도:</span><span><span class="hljs-subst">{$port}</span></span><span>\n";
}
</span></span>이 기능은보다 강력한 판단을 내릴 것입니다. GetServbyName 리턴 값을 확인하고 포트 번호가 법적 범위 내에 있는지 확인하십시오 (1–65535).
<span><span><span class="hljs-meta"><?php</span></span><span>
<span class="hljs-comment">/**
* 判断서비스 이름称是否有效(在이 기계제공하다数据库中有对应端口)
*
* </span></span><span><span class="hljs-doctag">@param</span></span><span> string $service 서비스 이름称,예를 들어 'http'、'ssh'
* </span><span><span class="hljs-doctag">@param</span></span><span> string $protocol 규약 'tcp' 또는 'udp'
* </span><span><span class="hljs-doctag">@return</span></span><span> bool 반품 true 그것은 유효한 것을 의미합니다(법적 항구를 찾으십시오),false 表示无效또는出错
*/
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">is_service_name_valid</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$protocol</span></span><span> = </span><span><span class="hljs-string">'tcp'</span></span><span>): </span><span><span class="hljs-title">bool</span></span><span>
{
</span><span><span class="hljs-comment">// 정규화 된 매개 변수</span></span><span>
</span><span><span class="hljs-variable">$protocol</span></span><span> = </span><span><span class="hljs-title function_ invoke__">strtolower</span></span><span>(</span><span><span class="hljs-variable">$protocol</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">in_array</span></span><span>(</span><span><span class="hljs-variable">$protocol</span></span><span>, [</span><span><span class="hljs-string">'tcp'</span></span><span>, </span><span><span class="hljs-string">'udp'</span></span><span>], </span><span><span class="hljs-literal">true</span></span><span>)) {
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">false</span></span><span>;
}
</span><span><span class="hljs-variable">$port</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">getservbyname</span></span><span>(</span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-variable">$protocol</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$port</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">false</span></span><span>;
}
</span><span><span class="hljs-comment">// 포트가 법적 범위인지 확인하십시오</span></span><span>
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-title function_ invoke__">is_int</span></span><span>(</span><span><span class="hljs-variable">$port</span></span><span>) && </span><span><span class="hljs-variable">$port</span></span><span> >= </span><span><span class="hljs-number">1</span></span><span> && </span><span><span class="hljs-variable">$port</span></span><span> <= </span><span><span class="hljs-number">65535</span></span><span>;
}
</span><span><span class="hljs-comment">// 예</span></span><span>
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">is_service_name_valid</span></span><span>(</span><span><span class="hljs-string">'http'</span></span><span>, </span><span><span class="hljs-string">'tcp'</span></span><span>)); </span><span><span class="hljs-comment">// 일반적으로 true</span></span><span>
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">is_service_name_valid</span></span><span>(</span><span><span class="hljs-string">'nosuchservice'</span></span><span>, </span><span><span class="hljs-string">'tcp'</span></span><span>)); </span><span><span class="hljs-comment">// false</span></span><span>
</span></span>GetServbyName은 운영 체제의 서비스 데이터베이스 (예 : /etc /services )를 쿼리합니다. 다른 시스템, 다른 설치 환경 및 다른 분포에는 다른 항목이 포함될 수 있습니다. 예를 들어, 일부 사용자 정의 서비스는 한 호스트에 존재하지만 다른 호스트에는 존재하지 않습니다.
이 기능은 서비스 이름에 포트 맵이 있는지 여부를 알려줍니다 . 이는 해당 포트의 서비스가 현재 실행 중이거나 연결되어 있음을 의미하지는 않습니다 . "서비스 가용성"을 확인 해야하는 경우 네트워크 연결 테스트 (예 : FSocopen , Stream_Socket_Client 또는 Socket_create / Socket_connect )를 수행해야합니다.
프로토콜은 'TCP' 또는 'UDP' (케이스 insensitive) 여야합니다. 다른 값은 유효하지 않은 것으로 간주됩니다.
서비스 이름의 존재를 결정하는 것은 첫 번째 단계 일뿐입니다. 원격 호스트 (또는 로컬 호스트)가 해당 서비스 포트에서 연결을 수락하는지 확인하려면 먼저 GetServbyName을 사용하여 포트를 얻은 다음 연결을 설정하려고 시도 할 수 있습니다.
<span><span><span class="hljs-meta"><?php</span></span><span>
<span class="hljs-comment">/**
* 먼저 사용하십시오 getservbyname 判断서비스 이름,접근성을 확인하려면 대상 호스트의 포트에 연결하십시오.
*
* </span></span><span><span class="hljs-doctag">@param</span></span><span> string $host 대상 호스트(IP 또는 호스트 이름)
* </span><span><span class="hljs-doctag">@param</span></span><span> string $service 서비스 이름称
* </span><span><span class="hljs-doctag">@param</span></span><span> string $protocol 'tcp' 또는 'udp'(여기에서만 구현되었습니다 tcp 연결 감지)
* </span><span><span class="hljs-doctag">@param</span></span><span> float $timeout 두번째(예를 들어 2.0)
* </span><span><span class="hljs-doctag">@return</span></span><span> bool true 포트가 발견되어 설정 될 수 있음을 나타냅니다. TCP 연결하다,false 그렇지 않으면
*/
</span><span><span class="hljs-function"><span class="hljs-keyword">function</span></span></span><span> </span><span><span class="hljs-title">is_service_reachable</span></span><span>(</span><span><span class="hljs-params"><span class="hljs-keyword">string</span></span></span><span> </span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-keyword">string</span></span><span> </span><span><span class="hljs-variable">$protocol</span></span><span> = </span><span><span class="hljs-string">'tcp'</span></span><span>, </span><span><span class="hljs-keyword">float</span></span><span> </span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">2.0</span></span><span>): </span><span><span class="hljs-title">bool</span></span><span>
{
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">strtolower</span></span><span>(</span><span><span class="hljs-variable">$protocol</span></span><span>) !== </span><span><span class="hljs-string">'tcp'</span></span><span>) {
</span><span><span class="hljs-comment">// 단순화:여기서만 수행하십시오 TCP 연결 감지;UDP 더 복잡한 탐지(无연결하다/확인 없음)</span></span><span>
</span><span><span class="hljs-keyword">throw</span></span><span> </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InvalidArgumentException</span></span><span>(</span><span><span class="hljs-string">'is_service_reachable 현재 만 지원됩니다 tcp 시험'</span></span><span>);
}
</span><span><span class="hljs-variable">$port</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">getservbyname</span></span><span>(</span><span><span class="hljs-variable">$service</span></span><span>, </span><span><span class="hljs-variable">$protocol</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$port</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span> || !</span><span><span class="hljs-title function_ invoke__">is_int</span></span><span>(</span><span><span class="hljs-variable">$port</span></span><span>) || </span><span><span class="hljs-variable">$port</span></span><span> < </span><span><span class="hljs-number">1</span></span><span> || </span><span><span class="hljs-variable">$port</span></span><span> > </span><span><span class="hljs-number">65535</span></span><span>) {
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">false</span></span><span>;
}
</span><span><span class="hljs-variable">$errno</span></span><span> = </span><span><span class="hljs-number">0</span></span><span>;
</span><span><span class="hljs-variable">$errstr</span></span><span> = </span><span><span class="hljs-string">''</span></span><span>;
</span><span><span class="hljs-variable">$fp</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">fsockopen</span></span><span>(</span><span><span class="hljs-variable">$host</span></span><span>, </span><span><span class="hljs-variable">$port</span></span><span>, </span><span><span class="hljs-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-variable">$timeout</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$fp</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">false</span></span><span>;
}
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$fp</span></span><span>);
</span><span><span class="hljs-keyword">return</span></span><span> </span><span><span class="hljs-literal">true</span></span><span>;
}
</span><span><span class="hljs-comment">// 예</span></span><span>
</span><span><span class="hljs-title function_ invoke__">var_dump</span></span><span>(</span><span><span class="hljs-title function_ invoke__">is_service_reachable</span></span><span>(</span><span><span class="hljs-string">'127.0.0.1'</span></span><span>, </span><span><span class="hljs-string">'ssh'</span></span><span>, </span><span><span class="hljs-string">'tcp'</span></span><span>, </span><span><span class="hljs-number">1.5</span></span><span>)); </span><span><span class="hljs-comment">// 이 기계 ssh 제공하다是否可达</span></span><span>
</span></span>참고 : UDP의 "도달 가능성"판단은 간단한 연결이 아닙니다. 일반적으로 프로브 패킷을 보내고 응답을 기다리거나 더 복잡한 소켓 API를 사용하고 (방화벽에서 폐기 할 수 있음). UDP 감지가 실제로 필요한 경우 애플리케이션 레이어 감지 로직을 구현하거나 특수 도구를 사용하십시오.
구성 확인 : 구성 인터페이스에서 사용자가 서비스 이름 (예 : SMTP , IMAP )을 입력하면 먼저 GetServByName을 사용하여 이름이 시스템에서 인식되는지 확인합니다. 인식되지 않으면 사용자는 포트 번호를 사용하거나 다른 서비스 이름을 선택하라는 메시지를 표시 할 수 있습니다.
호환성 : 시스템의 서비스 데이터베이스에 의존하지 마십시오-크로스 플랫폼 일관성이 필요할 때 폴백으로 인앱 매핑 테이블 (예 : 'http'=> 80 )을 유지 관리하십시오.
권한 및 보안 : 접근성 감지를 위해 포트를 연결하려고 할 때 네트워크 정책, 방화벽 및 요금 제한에주의하십시오. 남용이나 보안 경보를 유발하지 않기 위해 짧은 시간 안에 많은 수의 호스트를 자주 감지하지 마십시오.
오류 처리 : GetServbyName은 거짓을 반환 할 수 있습니다. 반환 값을 직접 사용하는 대신 코드에서 명시 적으로 처리하십시오.
GetServbyName ($ service, $ protocol)을 사용하여 서비스 이름에 로컬 시스템 서비스 데이터베이스에 포트 맵이 있는지 여부를 결정합니다 (포트 번호 또는 False를 반환).
유효성을 판단 할 때 반환 값 유형을 확인하고 포트가 1-65535 범위 내에 있는지 확인하는 것이 가장 좋습니다.
이 방법은 서비스를 사용할 수 있음을 의미하지는 않습니다 . 가용성이 필요한 경우 네트워크 연결 수준 (예 : FSOCCKOPEN 등)에서의 추가 탐지가 필요합니다.
플랫폼 차이점 : 다른 시스템의 서비스 데이터베이스 항목은 다릅니다. 크로스 플랫폼 요구 사항이있는 경우 폴백 매핑을 준비하거나 사용자에게 포트 번호를 제공하도록 요청하십시오.