简体   繁体   中英

PHP socket_close() Not Closing Server Connections

I am doing a 2 part app that requires two different socket connections to Window-based apps.

My app: Opens to read and query from an appliance via Socket #1. Socket #2 opens at the same time as Socket #1 to another appliance and waits to send commands to that appliance.

Both work fine for reading and sending as expected.

What I am running into is that I close Socket #2 on my side (client) the appliance side still shows an active connection and never seems to close them -- there are connections for a few days on there.

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($sock, $host, $port) or die('ERROR');

socket_write($sock, $buffer, $len);
print_r(simplexml_load_string(socket_read($sock, 65535)));

socket_shutdown($sock, 2);
socket_close($sock); 

I have tried socket_shutdown + socket_close, I have changed methods to pfsocketopen/fclose, fsocketopen/fclose, etc. I am not even sure there is anything I can do.

Thoughts?

So I tried a whole bunch of different things. Turns out that if I ctrl+c from the command line that will do it. So updated to send a ^C through the socket and its all good

I ran into the same problem and this worked for me.

  1. You'll need to set the Linger options, and for this to work you will need to be in block mode.

If l_onoff is non-zero and l_linger is zero, all the unsent data will be discarded and RST (reset) is sent to the peer in the case of a connection-oriented socket.

  1. Then use register_shutdown_function to

Registers a callback to be executed after script execution finishes or exit() is called.

// After socket_create $s
socket_set_block($s);

// Set Linger Options ($o)
$o=['l_onoff'=>1, 'l_linger'=>0];
socket_set_option($s, SOL_SOCKET, SO_LINGER, $o);

// Use register shutdown to trigger socket shutdown and close
register_shutdown_function('socket_shutdown', $s,2);
register_shutdown_function('socket_close', $s);

// do the rest of your stuff

This worked for me flawlessly about 10 times in a row. I was even able to CTRL-C the server, restart it in the seconds and send more from the client without him even noticing. For your reference and proof-of-work see working code snippet below.


  • Seems to be working without registering the shutdown function
  • The ending close function is most likely obsolete but haven't got there yet.
  • Client will loop for input (and press ENTER) and echo the server's response.
  • Server will echo message sent from the client and send it back to the client.

server.php

<?php
$h="localhost";
$p=65535;
set_time_limit(0);
$s=socket_create(AF_INET, SOCK_STREAM, 0) or die("create\n");

// START
socket_set_block($s);
$o=['l_onoff'=>1, 'l_linger'=>0];
socket_set_option($s, SOL_SOCKET, SO_LINGER, $o);
register_shutdown_function('socket_shutdown', $s,2);
register_shutdown_function('socket_close', $s);
// END

socket_bind($s, $h, $p) or die("bind\n");
socket_listen($s, 3) or die("listen\n");
while(true) {
  $a=socket_accept($s);# or die("accept\n");
  $i=socket_read($a, 1024);# or die("read\n");
  if($a && $i):
    echo $o='Client message:'.$i.PHP_EOL."\n";
    socket_write($a, $o, strlen ($o)) or die("write\n");
  endif;
  socket_close($a);
}
socket_close($s);

client.php

<?php
$h="127.0.0.1";
$p=65535;
while(true){
  echo "Input: \n";
  $i=trim(fgets(fopen("php://stdin","r")));
  $s=socket_create(AF_INET, SOCK_STREAM, 0) or die("create\n");

  // START
  socket_set_block($s);
  $o=['l_onoff'=>1, 'l_linger'=>0];
  socket_set_option($s, SOL_SOCKET, SO_LINGER, $o);
  register_shutdown_function('socket_shutdown', $s,2);
  register_shutdown_function('socket_close', $s);
  // END

  if($i&&$s):
    socket_connect($s, $h, $p) or die("connect\n");  
    socket_write($s, $i, strlen($i)) or die("write\n");
    $o=socket_read($s, 1024) or die("read\n");
    echo 'Server response: '.$o.PHP_EOL;
  endif;
}
socket_close($s);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM