簡體   English   中英

PHP socket_close() 不關閉服務器連接

[英]PHP socket_close() Not Closing Server Connections

我正在做一個兩部分的應用程序,它需要兩個不同的套接字連接到基於 Window 的應用程序。

我的應用程序:打開以通過 Socket #1 從設備讀取和查詢。 Socket #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 等。我什至不確定我能做些什么。

想法?

所以我嘗試了很多不同的東西。 事實證明,如果我從命令行按 ctrl+c 就可以了。 因此更新為通過套接字發送 ^C 並且一切正常

我遇到了同樣的問題,這對我有用。

  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)並回顯服務器的響應。
  • 服務器將回顯客戶端發送的消息並將其發送回客戶端。

服務器.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);

客戶端.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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM