Php how to force free socket

I am trying to use a thread to control socket connections. However, between the execution of my process / threads, the socket is not cleared, and I get an exception:

socket_create_listen (): cannot be associated with this address [98]: The address is already in use ... It will be permanently cleared after about 1 minute.

I searched the Internet but could not find a solution. Also, if you delete the code in the while (1) loop and execute my php file twice, it will also give the same error. I would expect all ressources to be cleared with the completion of the process.

<?php date_default_timezone_set('UTC'); echo date("H:i:s")."\tINFO: Starting my test\n"; $socket = null; //start our test try { echo date("H:i:s")."\tINFO: Setup socket for 1st time\n"; setupSocket(); usleep(100000); //send request to socket via curl $command = 'curl -s --no-buffer -d "{\"action\":\"getStatus\"}" -o socket.txt http://localhost:13000 > socket.log 2>&1 &'; exec($command); usleep(100000); echo date("H:i:s")."\tINFO: Now processing request\n"; processRequest(); echo date("H:i:s")."\tINFO: Close socket\n"; closeSocket(); } catch (Exception $e) { echo date("H:i:s")."\tERROR: ".$e->getMessage() ."\n"; } while(1) { try { echo date("H:i:s")."\tINFO: Try again to set socket...\n"; setupSocket(); usleep(100000); echo date("H:i:s")."\tINFO: Close socket\n"; closeSocket(); break; } catch (Exception $e) { echo date("H:i:s")."\tERROR: ".$e->getMessage() ."\n"; sleep(5); } } function setupSocket($port=13000) { global $socket, $logger; //Warning: socket_create_listen(): unable to bind to given address [98]: Address already in use in ... $socket = @socket_create_listen($port); if(!$socket) { throw new Exception('Failed to open socket with error \''.socket_strerror(socket_last_error()).'\''); } if(!socket_set_nonblock ($socket)) { throw new Exception('Failed to set the socket as non blocking with error \''.socket_strerror(socket_last_error($socket)).'\''); } //if(!socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1)) { // throw new Exception('Failed to set option \''.socket_strerror(socket_last_error($socket)).'\''); //} } //http://php.net/manual/en/function.socket-close.php //http://php.net/manual/en/function.socket-shutdown.php function closeSocket() { global $socket, $logger; //$arrOpt = array('l_onoff' => 1, 'l_linger' => 0); //socket_set_block($socket); //socket_set_option($socket, SOL_SOCKET, SO_LINGER, $arrOpt); if(!socket_shutdown($socket, 2)) { throw new Exception('Failed to shutdown socket with error \''.socket_strerror(socket_last_error($socket)).'\''); } socket_close($socket); } function processRequest() { global $socket; $client = socket_accept($socket); if ($client) { echo date("H:i:s")."\tINFO: Got connection\n"; //we don't care much about the content since this is a test, but still we read :) $request = socket_read($client, 1000000); $response = array( "head" => array( "HTTP/1.0 200 OK", "Content-Type: application/json" ), "body" => json_encode(array('Status'=>true)) ); $response['head'][] = sprintf("Content-Length: %d", strlen($response["body"])); socket_write($client, implode("\r\n", $response['head'])); socket_write($client, "\r\n\r\n"); socket_write($client, $response['body']); socket_close($client); } else { echo date("H:i:s")."\tINFO: Got no connection\n"; } } ?> 

Result:

  16:05:05 INFO: Starting my test 16:05:05 INFO: Setup socket for 1st time 16:05:05 INFO: Now processing request 16:05:05 INFO: Got connection 16:05:05 INFO: Close socket 16:05:05 INFO: Try again to set socket... 16:05:05 ERROR: Failed to open socket with error 'Address already in use' 16:05:10 INFO: Try again to set socket... 16:05:10 ERROR: Failed to open socket with error 'Address already in use' 16:05:15 INFO: Try again to set socket... 16:05:15 ERROR: Failed to open socket with error 'Address already in use' 16:05:20 INFO: Try again to set socket... 16:05:20 ERROR: Failed to open socket with error 'Address already in use' 16:05:25 INFO: Try again to set socket... 16:05:25 ERROR: Failed to open socket with error 'Address already in use' 16:05:30 INFO: Try again to set socket... 16:05:30 ERROR: Failed to open socket with error 'Address already in use' 16:05:35 INFO: Try again to set socket... 16:05:35 ERROR: Failed to open socket with error 'Address already in use' 16:05:40 INFO: Try again to set socket... 16:05:40 ERROR: Failed to open socket with error 'Address already in use' 16:05:45 INFO: Try again to set socket... 16:05:45 ERROR: Failed to open socket with error 'Address already in use' 16:05:50 INFO: Try again to set socket... 16:05:50 ERROR: Failed to open socket with error 'Address already in use' 16:05:55 INFO: Try again to set socket... 16:05:55 ERROR: Failed to open socket with error 'Address already in use' 16:06:00 INFO: Try again to set socket... 16:06:00 ERROR: Failed to open socket with error 'Address already in use' 16:06:05 INFO: Try again to set socket... 16:06:05 ERROR: Failed to open socket with error 'Address already in use' 16:06:10 INFO: Try again to set socket... 16:06:11 INFO: Close socket 

I am using Linux Ubuntu 14.04 and PHP 5.6.8 compiled with pthread.

+6
source share
1 answer

The reason you cannot connect to the port is because your curl connection goes into TIME_WAIT state after closing the socket for this connection. One way to close the connection immediately is to add these two lines before the socket_close ($ client) statement as part of the processRequest () function.

 $linger = array ('l_linger' => 0, 'l_onoff' => 1); socket_set_option($client, SOL_SOCKET, SO_LINGER, $linger); 
+1
source

Source: https://habr.com/ru/post/989891/


All Articles