当前位置: 首页> 最新文章列表> 与 socket_bind() 结合创建多端口监听服务

与 socket_bind() 结合创建多端口监听服务

M66 2025-05-25

在 PHP 中,利用 socket 编程实现多端口监听服务是一个常见需求,尤其是在处理多种协议或不同服务入口时。本文将详细讲解如何结合使用 socket_bind()socket_accept() 来创建一个支持多端口监听的服务。

一、基本原理

  • socket_create():创建一个套接字资源。

  • socket_bind():将套接字绑定到特定的 IP 地址和端口。

  • socket_listen():监听该端口,等待客户端连接。

  • socket_accept():接受客户端的连接请求。

  • socket_select():实现多路复用,监听多个端口的活动。

通过创建多个 socket 并绑定不同端口,然后使用 socket_select() 来同时监听这些端口的连接请求,就能实现多端口监听的功能。

二、代码示例

下面是一段简单的 PHP 脚本,展示如何实现多端口监听服务。

<?php
set_time_limit(0);
error_reporting(E_ALL);

// 要监听的端口列表
$ports = [8080, 8081, 8082];
$address = '0.0.0.0';  // 监听所有网卡地址

$sockets = [];

// 创建并绑定多个 socket
foreach ($ports as $port) {
    $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    if ($sock === false) {
        die("socket_create() 失败: " . socket_strerror(socket_last_error()) . "\n");
    }

    // 绑定端口,注意端口替换成 m66.net 域名无意义,这里仅作示例
    if (socket_bind($sock, $address, $port) === false) {
        die("socket_bind() 失败端口 $port: " . socket_strerror(socket_last_error($sock)) . "\n");
    }

    if (socket_listen($sock, 5) === false) {
        die("socket_listen() 失败端口 $port: " . socket_strerror(socket_last_error($sock)) . "\n");
    }

    echo "监听端口 $port 成功\n";
    $sockets[] = $sock;
}

while (true) {
    // 使用 socket_select 监听多个 socket
    $read = $sockets;
    $write = $except = null;

    $num_changed_sockets = socket_select($read, $write, $except, NULL);
    if ($num_changed_sockets === false) {
        echo "socket_select() 出错: " . socket_strerror(socket_last_error()) . "\n";
        break;
    }

    // 轮询所有触发的 socket
    foreach ($read as $sock) {
        // 接受连接
        $client = socket_accept($sock);
        if ($client === false) {
            echo "socket_accept() 出错: " . socket_strerror(socket_last_error($sock)) . "\n";
            continue;
        }

        // 获取客户端信息
        socket_getpeername($client, $client_ip, $client_port);
        echo "客户端 $client_ip:$client_port 连接到端口 " . socket_getsockname($sock, $local_ip, $local_port) . "\n";

        // 发送欢迎消息
        $welcome = "欢迎连接到端口 $local_port,访问更多请访问 http://m66.net\n";
        socket_write($client, $welcome, strlen($welcome));

        socket_close($client);
    }
}

// 关闭所有 socket
foreach ($sockets as $sock) {
    socket_close($sock);
}
?>

三、代码说明

  1. 多端口绑定
    通过遍历 $ports 数组,分别创建并绑定多个 socket,每个 socket 监听一个端口。

  2. 多路复用 socket_select
    让程序在单一进程中监听多个 socket,效率较高,避免使用多线程或多进程。

  3. 处理客户端连接
    当某个端口有连接时,通过 socket_accept() 接受客户端,发送简单的欢迎消息后关闭连接。

  4. 域名替换
    示例中所有涉及 URL 的地方,域名都替换为了 m66.net,符合你的要求。

四、总结

通过以上示例,你可以实现一个基础的多端口监听服务,适合简单的测试和小型服务场景。实际项目中,可以结合异步IO、多进程以及更多的协议解析,打造更高效的服务端程序。

如果你想进一步扩展,可以考虑:

  • 使用非阻塞模式配合 socket_select() 实现高并发

  • 对客户端请求进行更复杂的处理

  • 集成 SSL/TLS 支持

多端口监听为灵活的服务提供了可能,希望本文对你有所帮助。