PHP socket_close()不关闭服务器连接

时间:2018-02-09 20:20:20

标签: php sockets

我正在做一个2部分的应用程序,需要两个不同的套接字连接到基于Window的应用程序。

我的应用:打开以通过套接字#1从设备读取和查询。套接字#2与Socket#1同时打开到另一个设备,并等待向该设备发送命令。

两者都可以正常阅读和发送。

我遇到的是我关闭了Socket#2(客户端),设备端仍显示活动连接,似乎从未关闭它们 - 那里有连接几天。

$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); 

我已经尝试过socket_shutdown + socket_close,我已经将方法更改为pfsocketopen / fclose,fsocketopen / fclose等。我甚至不确定我能做什么。

思想?

2 个答案:

答案 0 :(得分:0)

所以我尝试了很多不同的东西。事实证明,如果我从命令行ctrl + c将执行它。如此更新以通过套接字发送^ C及其所有好的

答案 1 :(得分:0)

我遇到了同样的问题,这对我有用。

  1. 您需要设置 Linger 选项,为此您需要处于 block 模式。
<块引用>

如果 l_onoff 非零且 l_linger 为零,则在面向连接的套接字的情况下,将丢弃所有未发送的数据并向对等方发送 RST(重置)。

  1. 然后使用 register_shutdown_function
<块引用>

注册一个回调,在脚本执行完成或 exit() 被调用。

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

这对我来说连续 10 次都完美无缺。我什至能够 CTRL-C 服务器,在几秒钟内重新启动它并从客户端发送更多信息,而他甚至没有注意到。如需参考和工作证明,请参阅下面的工作代码片段。


  • 似乎无需注册关机功能即可工作
  • 结束关闭函数很可能已过时,但尚未实现。
  • 客户端将循环输入(并按 ENTER)并回显服务器的响应。
  • 服务器将回显客户端发送的消息并将其发送回客户端。

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);