php socket内存泄漏?

wudihzh

用workerman写好了服务端的程序,现在用PHP写了个测试程序,模拟多个用户同时访问服务端,测试服务器的处理能力,代码如下:

<?php

class Client {

    private $lastSendTime = 0;
    private $SEND_INTERVAL = 60;
    private $socket;
    private static $global_id = 0;
    private static $host;
    private static $port;
    private $id;    

    public function __construct($host, $port) {
        self::$host = $host;
        self::$port = $port;

        self::$global_id ++;
        $this->id = self::$global_id;
        $this->lastSendTime = mt_rand(time() - $this->SEND_INTERVAL * 2, time() - $this->SEND_INTERVAL);
    }

    public function connect() {
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($this->socket) {
            if (socket_connect($this->socket, self::$host, self::$port) && socket_set_nonblock($this->socket)) {
                return TRUE;
            }
        }

        $errno = socket_last_error($this->socket);
        $errstr = socket_strerror($errno);
        echo 'Client connect failed..' . PHP_EOL . $errno . ': ' . $errstr . PHP_EOL;
        socket_close($this->socket);

        return FALSE;
    }

    public function sendCommand($command) {
        $now = time();
        if ($now - $this->lastSendTime > $this->SEND_INTERVAL) {
            if (socket_write($this->socket, $command)) {
                //echo 'Client ' . $this->id . ' send message successfully' . PHP_EOL;
                $this->lastSendTime = $now;
            }
            else {
                $errno = socket_last_error($this->socket);
                $errstr = socket_strerror($errno);
                if ($errno == 10054 || $errno == 10053) {
                    echo 'Client ' . $this->id . ' connect again' . PHP_EOL;
                    socket_close($this->socket);
                    $this->connect();
                }
                else {
                    echo 'Client send message failed' . PHP_EOL;
                    echo $errno . ': ' . $errstr . PHP_EOL;
                }
            }
        }
    }
}

if (count($argv) != 2) {
    exit('1 param is required.');
}

$port = 4832;
$host = 'xxxx.xxxx.xxx.xxx';
$total = (int) $argv;
$clients = [];
$command = 'XXx';
$stat = 0;

for ($i = 0; $i < $total; $i++) {
    $c = new Client($host, $port);
    if ($c->connect()) {
        echo (++$stat) . ' clients connected' . PHP_EOL;
        $clients[] = $c;      
        $c->sendCommand($command);
    }
}

echo count($clients) . ' Clients are connected.' . PHP_EOL;

while (true) {
    foreach ($clients as $c) {
        $c->sendCommand($command);
    }
    sleep(1);
    //echo memory_get_usage(true) . PHP_EOL;
}

在windows下用cmd(命令行模式)来运行,发现一段时间后,系统的已使用内存越来越高,把程序结束后,内存占用马上恢复到原来的水平。但是我在程序中使用memory_get_usage方法来检查进程占用的内存时,却发现长时间都是不变的,在任务管理器中查看进程占用内存时,也是不变的。我想长时间运行测试程序,以检查服务端的稳定性,但是大概运行一天后,内存就不够用了。就教大神,我的内存到底去哪里了??

阅读 3715
3个回答

wudihzh

我现在怀疑是不是我的程序没有读取服务器返回的数据,导致数据都堆积到内存了?但是我并不关心服务器的回复信息,而且我用的是非阻塞模式,要读取回复信息好像挺麻烦的。如果果真是这个原因,有什么办法让程序直接丢弃服务的回复信息?

  • 暂无评论
walkor

客户端必须读数据,不然数据都会积压在每个socket连接的读缓冲区,导致内存不断增长。如果每个连接的socket读缓冲区都满了,则客户端无法再接收到数据

  • wudihzh 2015-03-13

    嗯嗯,测试过了,确实是这样,感谢~~

mazhaozi

这也是我一直的疑问

  • 暂无评论