Socket resource id overflowing

2020-03-26 06:53发布

问题:

What: I have a PHP script running that awaits socket connections. When I connect to the socket the script prints out the resource ID.

Problem: The resource ID does not increment by 1 instead by an average of 306,000. This is of course reaching a bigger problem and overflowing. Causing my code to eventually break.

Research: I cant find any documentation that would support me(the programmer) needing to control this. I did find the following link were someone states the same issue.

Thoughts: I would think the system would manage this. If I need to manage the resource ID number then how do I do it.

Code snip:

<?php
chdir( dirname ( __FILE__ ) );
echo "Waiting for port!\n";
$file = 'change.txt';//change query

do{
$sock = @socket_create_listen('12346'); //port im listening too
sleep(1);
}
while(!(@socket_getsockname($sock, $addr, $port))); 

echo "Server Listening on $addr:$port\n"; 
socket_set_nonblock($sock);
echo"Awaiting Connection\n";

while(true)
{
    if($newc = @socket_accept($sock))
    {
        socket_set_nonblock($newc);
        echo "Client $newc has connected\n";

    }
    $current = file_get_contents($file);
}

?>

Help: The idea is (If you continuously connect to the socket the resource ID would overflow). My code is far to large to paste in, but I reduced it to show the problem:

A) What could cause unusual increments in the resource id.

B) If determining the root cause of the unusual increment problem is not feasible maybe how to manage the resource id could help.

Findings: The last command "file_get_contents..." if this line is commented out the code works correctly and the resource id is incremented properly. If not commented out and a sleep is added the increment value is much better but not correct (ie jump 5 or 6 values). Im not sure whats really going on though.

Thanks

回答1:

PHP does not re-use resource IDs internally, so eventually you'll hit a problem with PHP using them all up, causing the warning you got. See the bug report. Since a bunch of things in PHP will register a resource, incrementing the resource ID, this bug is easy to encounter in long running scripts.

The max ID depends on your architecture. You can print the constant PHP_INT_MAX to get the number for your install, but on 32 bit systems it's generally 2,147,483,647. It's significantly higher on 64 bit systems. Mine prints out 9,223,372,036,854,775,807. You're pretty unlikely to exhaust the resource ID limit on 64 bit systems.

Also, you call file_get_contents in your unbounded while (true) loop. You have no sleep period between each iteration of the while loop, so the loop basically executes as fast as it can. Each file_get_contents call results in the resource ID pointer being incremented by 2, as it uses 2 resources under the hood. Example:

<?php
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #4
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #5
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #6
file_get_contents('/etc/hosts');
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #9
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #10
echo gmp_init("0x41682179fbf5"). "\n"; // Resource id #11