Jump to content

Using Streams to connect non-blocking


Pannekoek

Recommended Posts

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?

Link to comment
Share on other sites

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.

--

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.