#43782 [Opn->Csd]: feof() does not detect timeout on socket

From: Date: Sun, 10 Jan 2010 23:38:56 +0000
Subject: #43782 [Opn->Csd]: feof() does not detect timeout on socket
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-3671@lists.php.net to get a copy of this message
 ID:               43782
 Updated by:       kalle@php.net
 Reported By:      ml at foofree dot sk
-Status:           Open
+Status:           Closed
 Bug Type:         Documentation problem
 Operating System: *
 PHP Version:      5.2,5.3CVS (2008-07-15)
-Assigned To:      
+Assigned To:      kalle
 New Comment:

This bug has been fixed in the documentation's XML sources. Since the
online and downloadable versions of the documentation need some time
to get updated, we would like to ask you to be a bit patient.

Thank you for the report, and for helping us make our documentation
better.




Previous Comments:
------------------------------------------------------------------------

[2010-01-10 23:38:48] svn@php.net

Automatic comment from SVN on behalf of kalle
Revision: http://svn.php.net/viewvc/?view=revision&revision=293364
Log: Fixed bug #43782 (feof() does not detect timeout on socket)

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

[2009-03-19 02:53:38] mark at markparnell dot com dot au

I've just run into this same bug and agree that it would be much better
fixed than just changing the documentation. It was causing threads to
hang on the web server to the point that we were having to restart the
server every 5 hours or it would run out of connections.

FWIW I've implemented a workaround for now like this:

	$hack_time = microtime(true);
	while(!feof($fp) && (microtime(true)-$hack_time) < 20){
		$string.=fgets($fp,128);
	}

Like x2012x's solution it's not ideal, but it's saved me for now.

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

[2008-12-01 04:33:15] x2012x at gmail dot com

As a temporary work around, I've implemented a check against the socket
responses and if the socket response is empty, I am assuming that the
connection can be closed. This is certainly not the most desirable
method and would not be needed if the socket timeout worked properly.

Workaround:
===========
// Establish a socket connection with the designated host.
$_SESSION['socketCon'] = fsockopen($strHost, $strPort, $errNum,
$errStr,
$strTimeOut);
stream_set_blocking($_SESSION['socketCon'], 1);
stream_set_timeout($_SESSION['socketCon'], 3);
// Check to see if the socket connection could be established, if not
display relevant error info.
if (!$_SESSION['socketCon'])
 {
   $errors .= "Cannot connect to socket!!!\r\n";
   $errors .= "Details:\r\n";
   $errors .= "Host: $strHost\r\n";
   $errors .= "Port: $strPort\r\n";
   $errors .= "Timeout value: $strTimeOut\r\n";
   $errors .= "Error #: $errNum\r\n";
   $errors .= "Response: $errStr\r\n";
   errorHandler($errors, "ERROR");
   stopTrans();
   $console->destroy();
   return 1;
 }
else
 {
   // Notify the user that a socket connection has been established.
   updateOutPut($console, $outPut, "Connected to $strHost on port
$strPort\r");

   // Send the terminal transaction data over the established socket
connection.
   updateOutPut($console, $outPut, "\rTransmitting: \r");
   updateOutPut($console, $outPut, "$sendingData ");
   fputs($_SESSION['socketCon'], $sendingData . "\n");       
		
   // Loop through the response from the server and print it to
console.
   updateOutPut($console, $outPut,"\r\rResponse: \r");
   
   // WORKAROUND
   $resCheck = 0;
   while($resCheck == 0) 
    {
      $response = fgets($_SESSION['socketCon'], 4096);
      updateOutPut($console, $outPut, "$response");
      if ($response == '')
       {
         $resCheck = 1;
       }
    } 
   // Close the socket connection.
   fclose($_SESSION['socketCon']);
 }
===========

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

[2008-11-27 14:17:55] x2012x at ymail dot com

From an end-user/developer standpoint, it would be preferred to have
this issue addressed instead of just updating the documentation. 

Here's another real-world example of the issue being encountered.

Excerpt:
========
// Establish a socket connection with the designated host.
$_SESSION['socketCon'] = fsockopen($strHost, $strPort, $errNum,
$errStr, $strTimeOut);
stream_set_blocking($_SESSION['socketCon'], 1);
stream_set_timeout($_SESSION['socketCon'], 3);
// Check to see if the socket connection could be established, if not
display relevant error info.
if (!$_SESSION['socketCon'])
 {
   $errors .= "Cannot connect to socket!!!\r\n";
   $errors .= "Details:\r\n";
   $errors .= "Host: $strHost\r\n";
   $errors .= "Port: $strPort\r\n";
   $errors .= "Timeout value: $strTimeOut\r\n";
   $errors .= "Error #: $errNum\r\n";
   $errors .= "Response: $errStr\r\n";
   errorHandler($errors, "ERROR");
   stopTrans();
   $console->destroy();
   return 1;
 }
else
 {
   // Notify the user that a socket connection has been established.
   updateOutPut($console, $outPut, "Connected to $strHost on port
$strPort\r");

   // Send the terminal transaction data over the established socket
connection.
   updateOutPut($console, $outPut, "\rTransmitting: \r");
   updateOutPut($console, $outPut, "$sendingData ");
   fputs($_SESSION['socketCon'], $sendingData . "\n");       
		
   // Loop through the response from the server and print it to
console.
   updateOutPut($console, $outPut,"\r\rResponse: \r");
   while(!feof($_SESSION['socketCon'])) 
    {
      $response = fgets($_SESSION['socketCon'], 4096);
      updateOutPut($console, $outPut, "$response");
    } 
   // Close the socket connection.
   fclose($_SESSION['socketCon']);
 }
========

If the socket server does not close the connection in the above !feof
while loop, the function will get stuck looping in the while loop. It is
my opinion that this sort of functionality ( a working timeout value )
is very fundamental. I've been using PHP for many years now and I am
glad that this is the first bug that I've encountered to be major in my
opinion. Please consider addressing the actual bug and not just
modifying documentation. Thanks for your time.

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

[2008-11-24 15:38:52] dsp@php.net

The patch was reverted as it caused problems. We might want to edit the
documentation instead.

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

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/43782

-- 
Edit this bug report at http://bugs.php.net/?id=43782&edit=1



Thread (6 messages)

« previous php.doc.bugs (#3671) next »