【发布时间】:2012-03-19 14:29:03
【问题描述】:
我在 php 脚本中使用以下代码来处理通过 http 传入的数据并将其转发到另一个模块并等待响应。然后它关闭套接字。
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($sock,$host,$port) or die("<?xml version=\"1.0\"?>");
if (!socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1)) {
echo socket_strerror(socket_last_error($sock));
exit;
}
$arrOpt = array('l_onoff' => 1, 'l_linger' => 1);
socket_set_block($sock);
socket_set_option($sock, SOL_SOCKET, SO_LINGER, $arrOpt);
$address = gethostbyname($host);
$msg = $url;
$len = strlen($msg);
socket_sendto($sock, $msg, $len, 0, $remotehost, $remoteport) ;
socket_recvfrom($sock, $buff, 1000, 0, $host, $newport);
socket_close($sock);
面临的问题是响应被正确接收并且socket_close错误也返回成功(socket_last_error的输出)。但在那之后,如果我执行 netstat,我会看到正在使用的端口并且进程(/proc/pid/status 的输出)处于睡眠状态。 这种行为本质上是随机的,我在 Amazon EC2 云上使用 PHP 版本 5.3.8。
【问题讨论】:
-
可能只是剪切/粘贴错字,但您在 socket_bind() 行上缺少
");。 -
This behavior is random in nature- 你的意思是它并不总是发生?可能是garbage collection的函数,试试下面的方法:1)尝试在最后一行显式设置$sock = NULL;2)尝试在最后一行调用gc_collect_cycles()。 -
@Dave:行为是随机的,意味着对于某些接收到的请求,套接字被正确关闭并释放所有资源。但是对于某些请求,套接字的关闭是不完整的,netstat 结果显示这些套接字仍在使用中。
-
对上面的 GC 建议有帮助吗?
-
设置 $sock = NULL 并调用 gc_collect_cycles 后没有变化,它返回零值。有什么方法可以知道调用 socket_close() 后是否所有的系统资源都被释放了?