【问题标题】:PHP UDP socket memory leakPHP UDP 套接字内存泄漏
【发布时间】:2015-08-26 09:41:10
【问题描述】:

我有这段 PHP 代码,它是一个非常基本的 UDP 服务器。问题是它有一个让我发疯的内存泄漏。

事实/观察: - 如果脚本自己启动,它将耗尽内存。 - 当我在 while 循环中输出内存使用情况或任何文本时,它不会崩溃并且会显示一致的内存使用情况。 - 但是,当客户端连接到服务器时,while 循环的每次迭代都会消耗额外的 96 字节内存,直到它崩溃。客户端甚至不需要发送数据。事实上,大多数迭代都是由 process() 函数中的第一个 IF 语句(如果缓冲区为空)处理,然后是 return。 - 为脚本/进程分配更多内存只会将不可避免的崩溃延迟一段时间。 - 从 CentOS 6 上的 PHP5.3.3 升级到 5.4 没有帮助。

任何帮助或指点将不胜感激!

<?php

ini_set( 'display_errors', true );

class UDP_Server {

    protected $_socket = null;
    protected $_host = '';
    protected $_port = 0;
    protected $_clients = array();
    protected $_debug = false;

    public function __construct( $host = '', $port = 0 ) {
        $this->_host = $host;
        $this->_port = $port;
        $this->_socket = $this->_create_udp_server( $host, $port );
    }

    public function set_debug( $value = false ) {
        $this->_debug = $value;
    }

    public function process() {
        $buffer = stream_socket_recvfrom( $this->_socket, 1024, 0, $remote_host );
        if( empty( $buffer ) ) {
            return;
        }

        if( $this->_debug ) {
            echo $remote_host, ': ', $buffer, "\n";
        }

        if( strpos( $buffer, 'udp.register.ip' ) !== false ) {
            if( ! in_array( $remote_host, $this->_clients ) ) {
                $this->_clients[] = $remote_host;
            }

            stream_socket_sendto( $this->_socket, 'udp.register.complete', 0, $remote_host );
            return;
        }

        foreach( $this->_clients as $client ) {
            if( $client === $remote_host ) {
                continue;
            }
            stream_socket_sendto( $this->_socket, $buffer, 0, $client );
        }
    }

    public function __destruct() {
        fclose( $this->_socket );
    }

    protected static function _create_udp_server( $host = '0.0.0.0', $port = 0 ) {
        $address = 'udp://' . $host . ':' . $port;
        $socket = stream_socket_server( $address, $error_number, $error_message, STREAM_SERVER_BIND );
        if( ! $socket ) {
            die( 'could not create UDP server for ' . $address . '; Reason: [' . $error_number . '] - ' . $error_message );
        }

        stream_set_blocking( $socket, 0 );
        return $socket;
    }

}

$at_data_server  = new UDP_Server( '0.0.0.0', 5556 );
$at_data_server->set_debug( true );

while( 1 ) {
    $at_data_server->process();
}

【问题讨论】:

  • 在你的循环中,输出你的客户端数组,看看它是否在每次迭代中只有一个连接而增长。让我知道是否有。这通常是一个常见问题。前段时间我用socket io有过。断开连接时永远不会从阵列中删除我的客户
  • 我添加了另一个函数来回显大小并遍历客户端数组。阵列中只有 1 个客户端,它没有增长。 PHP 仍然因致命错误而死,表明内存已耗尽。

标签: php sockets memory-leaks udp


【解决方案1】:

您的代码似乎符合此错误报告中的条件 - https://bugs.php.net/bug.php?id=71613

尽可能避免使用stream_socket_recvfrom() 的第四个参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 2015-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多