php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #30852 socket_select() fails when managing large numbers of sockets
Submitted: 2004-11-21 00:44 UTC Modified: 2004-11-21 22:21 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: jed at jed dot bz Assigned:
Status: Closed Package: Sockets related
PHP Version: 5.0.2 OS: Windows XP SP2
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: jed at jed dot bz
New email:
PHP Version: OS:

 

 [2004-11-21 00:44 UTC] jed at jed dot bz
Description:
------------
Posted to php.general. Posted here on behalf of original bug discoverer, as I wrote a large test case for it.

PHP 5.0.2 CLI
Windows XP SP 2 with DEP excepted for PHP-CLI
  (DEP *was* a problem early, but I excepted it for php.exe)

socket_select() will fail when managing a large number of sockets. The sockets extension itself can manage a bunch, but when socket_select() is attempted with a 'read' array larger than exactly 64 sockets, it prints out the following message and dies:

Warning: socket_select(): unable to select [0]: An operation was attempted on something that is not a socket.                                                   

PHP's problem? My problem? A print_r of the array before feeding it to socket_select shows this:

Array                    
(                        
    [1] => Resource id #4
    [2] => Resource id #5
    [3] => Resource id #6
    (...)
    [64] => Resource id #67
    [65] => Resource id #68
)                          

Valid resources, I'd assume. Zero-basing the array causes the same problem. If there are more than exactly 64 sockets in the array fed to socket_select for the read parameter socket_select() will fail.

Due to lack of time I'll only submit the test case for read, but write and except might be prone to the same problem. Let's tackle one at a time.

Latest CVS was unusable as the sockets extension currently doesn't link correctly (numerous PHP startup warnings were encountered when starting php just for php -v)... The snaps I used to obtain this result were

    5.0.x-dev 200411201730 ("5.0.3-dev")
    5.1.x-dev 200411201930

Might have been misconfiguration on my end, because 5.0.x popped up a box reporting a mismatch between extensions even after I changed extension_dir to the snapshot package's extensions.

Reproduce code:
---------------
The Server
   http://labs.jed.bz/HCJ/server.php.txt

The Load Client
   http://labs.jed.bz/HCJ/load.php.txt

When executing, make sure $max_connections in the server is exactly equal to $connections in the load tester (or, if you prefer, make it one under, and telnet in to the server to make the last one).

Expected result:
----------------
...
connecting #65 of 65 ... ok
                         
waiting for spew         
Array                    
(                        
    ...
)                        
spew!                    
                         
done!                    

Actual result:
--------------
    [63] => Resource id #67                                                     
    [64] => Resource id #68                                                     
)                                                                               
                                                                                
Warning: socket_select(): unable to select [0]: An operation was attempted on something that is not a socket.                                                   
 in F:\Projects\HCJ\load.php on line 39                                         
spew!                                                                           
                                                                                
done!                          

----------------

This appeared in my debugger output while I was messing with getting a backtrace (possible in VS?). Interest you?

First-chance exception at 0x7c81eb33 in php.exe: 0x000006A6: The binding handle is invalid.

----------------

I can't recompile with debug symbols at this point, I'm unfortunately pressed for time. Perhaps someone can run it through VS and see what comes up.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-11-21 14:52 UTC] wez@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5-STABLE-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.0-win32-latest.zip

Windows can only select(), by default, a maximum of 64 handles at one time.

5.0.3 changes this limit to 256 in the Streams subsystem; you can try this yourself with a stable snapshot and using the native functions stream_socket_client(), stream_socket_server() and stream_select().

I would expect this change to also work with the sockets extension.  It builds ok here with 5.0.3, so it sounds like you do indeed have a configuration issue.

Short version: try a 5.0.3 snapshot, it should behave better
.
 [2004-11-21 22:21 UTC] jed at jed dot bz
Thumbs up, Wez.

-#include <winsock2.h>
+#define FD_SETSIZE 512
+#include <winsock2.h>

Too bad that can't be turned into a php.ini option for the Sockets extension...
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sun Jan 05 09:01:27 2025 UTC