Pannekoek Posted August 5, 2012 Share Posted August 5, 2012 Hello lads, I'm hoping someone here can say me why the following piece of code is not working as expected: <?php // Create stream $sock = stream_socket_client ('tcp://www.google.nl:80', $i_Errno, $s_Errstr, null, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT); sleep (1); $r = $w = $e = array (); $r [] = $sock; echo 'selecting..' . PHP_EOL; $i_Changed = stream_select ($r, $w, $e, null); print_r ($i_Changed); I would expect stream_select () to return immediately with $r containing one element (the stream resource). Especially since the scripts halts one second. That should be more than enough to complete the connection attempt. And indeed, the stream is connected since fread and fwrite will succeed. However, stream_select does not agree with me. How come? Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/ Share on other sites More sharing options...
requinix Posted August 5, 2012 Share Posted August 5, 2012 So that's what you expect. What does it actually do? Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/#findComment-1367052 Share on other sites More sharing options...
Pannekoek Posted August 6, 2012 Author Share Posted August 6, 2012 stream select should modify the given arrays by reference indicating that a certain event would not block; in this case, readability would mean that the connection has been established. For reference: see http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=vs.85%29.aspx Implementation for this function is the same on linux systems etc. -- Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/#findComment-1367066 Share on other sites More sharing options...
KevinM1 Posted August 6, 2012 Share Posted August 6, 2012 In PHP, arrays are not a reference type. To have the arrays modified by reference, you'll need to specify it manually: $i_Changed = stream_select (&$r, &$w, &$e, null); Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/#findComment-1367067 Share on other sites More sharing options...
requinix Posted August 6, 2012 Share Posted August 6, 2012 In PHP, arrays are not a reference type. To have the arrays modified by reference, you'll need to specify it manually: $i_Changed = stream_select (&$r, &$w, &$e, null); Actually any variable can be passed by reference if the function signature specifies it. Like stream_select()s does. @Pannekoek: I know what stream_select() does. I meant that if your code does not produce the results you expect, what results does it produce? Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/#findComment-1367077 Share on other sites More sharing options...
Pannekoek Posted August 6, 2012 Author Share Posted August 6, 2012 In PHP, arrays are not a reference type. To have the arrays modified by reference, you'll need to specify it manually: $i_Changed = stream_select (&$r, &$w, &$e, null); as requinix said. -- One would expect stream_select () to return immediately with the socket in $r to indicate that the connection has been established. Anyhow, I fixed it to also check for writability on the stream. Then it returns immediately. Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/#findComment-1367101 Share on other sites More sharing options...
requinix Posted August 6, 2012 Share Posted August 6, 2012 The underlying select(3) will only return read sockets if there's something to read. Since with HTTP the client is the first to send data, it would block until the remote server gave up waiting and closed the connection. So yes, you have to select on the write stream because that's what you need to use first. Once you're done writing then you select on the read stream. Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/#findComment-1367218 Share on other sites More sharing options...
Pannekoek Posted August 6, 2012 Author Share Posted August 6, 2012 The underlying select(3) will only return read sockets if there's something to read. Since with HTTP the client is the first to send data, it would block until the remote server gave up waiting and closed the connection. So yes, you have to select on the write stream because that's what you need to use first. Once you're done writing then you select on the read stream. Aaarg I'm such a fool. I had the assumption that readability indicated that the connection was established for a while. But it has been on the MSDN site all along. Well, at least I know now. Thanks! Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/#findComment-1367245 Share on other sites More sharing options...
Christian F. Posted August 7, 2012 Share Posted August 7, 2012 Why are you referencing the MSDN library (which details WinSock in C++ for desktop applications only) for PHP functions? If I were you I'd use the PHP manual, as that's the relevant resource. For instance, by looking at the manual page for "stream_socket_client ()" you would have seen an example detailing everything you needed to do. So, use the manual for the language in question, whether it be PHP, C#, VB, Java, Perl or whatnot. That way you won't get bit by any subtle differences in the functions between them. Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/#findComment-1367419 Share on other sites More sharing options...
requinix Posted August 7, 2012 Share Posted August 7, 2012 Why are you referencing the MSDN library (which details WinSock in C++ for desktop applications only) for PHP functions? If I were you I'd use the PHP manual, as that's the relevant resource. For instance, by looking at the manual page for "stream_socket_client ()" you would have seen an example detailing everything you needed to do. Because PHP uses the system system for actual implementation. If you're running on Windows then you should consult the MSDN for what actually happens under the hood (beyond what PHP does), and if you're on *nix then consult the man pages. Sure the PHP manual says how to use the functions, but in most places it doesn't actually say how those functions behave deep down. Quote Link to comment https://forums.phpfreaks.com/topic/266713-using-streams-to-connect-non-blocking/#findComment-1367506 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.