ID: 46917
User updated by: jost_boekemeier at users dot sf dot net
Reported By: jost_boekemeier at users dot sf dot net
Status: Open
Bug Type: Streams related
Operating System: win32 only
PHP Version: 5.2.8
New Comment:
Here's a test case:
----------------- TestServer.java ------------------
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String args[]) throws Exception {
ServerSocket ss = new ServerSocket (9090);
System.out.println("accepting connections");
Socket s = ss.accept();
System.out.println("got initial request");
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();
while (true) {
out.write((byte)in.read());
out.flush();
System.out.println("waiting for next request");
}
}
}
---------TestClient.php--------------
<?php
function dieWithMsg() {
var_dump(error_get_last());
exit(1);
}
$errno = null; $errstr = null;
$conn = pfsockopen("127.0.0.1", 9090, $errno, $errstr, 30) or
dieWithMsg();
fwrite($conn, "\0") or dieWithMsg();
fread($conn, 1) or dieWithMsg();
echo "done";
exit(0);
?>
------------------------------------
To reproduce this bug on Windows XP and above, start the server with:
java TestServer
and refresh the
http://127.0.0.1/TestClient.php
a few times.
Then stop TestServer and start it again.
Refresh
http://127.0.0.1/TestClient.php
to get a broken connection from PHP.
I was able to reproduce this bug with yesterday's 5.2 windows
snapshot.
Regards,
Jost Bökemeier
Previous Comments:
------------------------------------------------------------------------
[2009-01-07 20:44:43] [email protected]
I changed the EGAIN to EWOULDBLOCK in the checking.
http://news.php.net/php.cvs/55434
------------------------------------------------------------------------
[2009-01-06 19:51:15] jost_boekemeier at users dot sf dot net
The windows equivalent to EAGAIN is EWOULDBLOCK or WSAEWOULDBLOCK.
Could it be that EAGAIN is 0 on windows?
Unfortunately I don't have the time and resources to debug this at the
moment.
------------------------------------------------------------------------
[2009-01-06 19:15:52] jost_boekemeier at users dot sf dot net
Well, the initialization is okay now.
However, the code still doesn't work on windows. Which means that
there's another bug.
The php_socket_errno() != EAGAIN looks suspicious.
"Depending on whether your socket is blocking or non-blocking, you
either get FD_CLOSE notification, or recv() returns 0 (graceful
disconnection), or recv() returns WSAECONNRESET error."
I don' see how the current code handles these three cases properly.
------------------------------------------------------------------------
[2009-01-06 17:41:49] [email protected]
Currently the WSASetLastError(0); already exists for Windows in the
code.
------------------------------------------------------------------------
[2009-01-06 16:15:20] jost_boekemeier at users dot sf dot net
Hi,
the code is okay for Linux, but on Windows it fails constantly.
+ WSASetLastError(0);
n = select(max_fd + 1, &rset, &wset, &eset, timeout >= 0 ? &tv :
NULL);
IMHO this means that select always returns EAGAIN on windows, so that
the following test cannot detect a broken connection. As I've said, I am
not sure what the EAGAIN test should do, anyway.
To reproduce this:
1) start a simple socket server on windows >= xp, call pfsockopen() and
let the PHP instance return to the HTTP server's pool w/o closing the
connection
2) kill the socket server and start it again
3) pull the PHP instance from the pool and call pfsockopen() again.
pfsockopen() will use the broken connection until you kill the pool
(i.e.: restart apache or IIS).
Regards,
Jost Bökemeier
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/46917
--
Edit this bug report at http://bugs.php.net/?id=46917&edit=1