當前位置: 首頁> 最新文章列表> 如何結合getservbyname 和getprotobyname 查詢協議和端口

如何結合getservbyname 和getprotobyname 查詢協議和端口

gitbox 2025-05-31

函數簡介

getservbyname()

getservbyname(string $service, string $protocol): int|false

此函數用於通過服務名和協議名查詢對應的端口號。例如,HTTP 服務通常使用TCP 協議並監聽80 端口。

 $port = getservbyname('http', 'tcp');
echo $port; // 輸出: 80

getprotobyname()

getprotobyname(string $name): int|false

此函數用於根據協議名(如"tcp"、"udp")獲取協議編號。例如:

 $proto = getprotobyname('tcp');
echo $proto; // 輸出: 6

結合使用的場景

當我們需要連接某個網絡服務時,往往不僅需要知道服務的端口號,還要知道使用的協議編號。例如,在使用socket_create()socket_connect()建立連接時,需要提供協議編號作為參數之一。

結合使用兩個函數可以如下操作:

 $service = 'http';
$protocol = 'tcp';

$port = getservbyname($service, $protocol);
$proto = getprotobyname($protocol);

if ($port === false || $proto === false) {
    die("無法解析服務或協議\n");
}

echo "服務 '{$service}' 使用端口: {$port}\n";
echo "協定 '{$protocol}' 的編號是: {$proto}\n";

實際應用示例:創建一個TCP socket

下面是一個簡單的使用這兩個函數創建TCP 連接的例子:

 $service = 'http';
$protocol = 'tcp';
$host = 'gitbox.net';

$port = getservbyname($service, $protocol);
$proto = getprotobyname($protocol);

if ($port === false || $proto === false) {
    die("服務或協定无法识别\n");
}

$socket = socket_create(AF_INET, SOCK_STREAM, $proto);
if ($socket === false) {
    die("無法創建 socket: " . socket_strerror(socket_last_error()) . "\n");
}

$result = socket_connect($socket, $host, $port);
if ($result === false) {
    die("無法連接到 {$host}:{$port} - " . socket_strerror(socket_last_error($socket)) . "\n");
}

echo "成功連接到 {$host}:{$port},使用協定编号 {$proto}\n";
socket_close($socket);

在這個示例中,我們利用getservbyname()獲取HTTP 對應的端口80,利用getprotobyname()獲取TCP 協議編號6,然後創建並連接一個TCP socket 到gitbox.net的80 端口。


注意事項

  1. 這兩個函數依賴系統的服務和協議定義文件,如/etc/ services和/etc/ protocols ,如果定義不完整可能導致解析失敗。

  2. 使用這些函數的結果應始終進行錯誤判斷,避免運行時出錯。

  3. 這些函數是對C 語言中getservbyname 和getprotobyname 的簡單封裝,對於熟悉底層socket 編程的用戶非常友好。