任何人都知道,如果像下面这样的异步连接失败,是否可以检索一些错误信息(如C中的getsockopt SO_ERROR):我没有使用套接字扩展,因为流提供了一个ssl Package 器
<?php
$ctx = stream_context_create();
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
$destination = "tcp://92.247.12.242:8081";
$socket = stream_socket_client($destination, $errno, $errstr,
10, STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT, $ctx);a
// plain socket
var_dump($socket);
// no error as expected
var_dump($errno);
var_dump($errstr);
stream_set_blocking($socket, false);
/* Prepare the read array */
$read = array($socket);
$write = array($socket);
$except = NULL;
if (false === ($num_changed_streams = stream_select($read, $write, $except, 10))) {
var_dump("select failed?");
/* Error handling */
} elseif ($num_changed_streams > 0) {
/* At least on one of the streams something interesting happened */
var_dump("event");
// read fails, so the connect fails but why?
$result = stream_socket_recvfrom($socket, 1024);
var_dump($result);
// no error again
var_dump($errno);
var_dump($errstr);
// nothing interesting
var_dump(stream_get_meta_data($socket));
}
// wont get called
function stream_notification_callback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) {
$args = func_get_args();
var_dump($args);
}
thx
3条答案
按热度按时间ohfgkhjo1#
我遇到了与描述相同的问题。我找到了一个解决办法:
我将每个“流” Package 在一个
Stream
类中,并设置了一个超时属性。在调用connect之前,我生成一个时间戳,指示超时应该发生的时间。然后在Manager
类中有一个循环,它调用stream_select()
。成功的连接被放置在
$write
阵列中。我在循环的底部有另一个调用,它调用$stream->checkTimeout()
。其中有一个stream_select()
调用,为tv_sec
和tv_usec
设置了0。如果$this->conn没有出现在$write
中,我假设它已经超时。p8h8hvxi2#
据我所知,流函数中的错误应该生成PHP警告消息。我认为唯一的方法是使用set_error_handler()捕获这些错误并在那里处理它们。
pinkon5k3#
我也遇到了这个问题。我发现的解决方案是使用stream_socket_get_name。如果你想把这一切都打包在一个漂亮的图书馆结帐http://drupal.org/project/httprl。它仍然需要Drupal,但主要用于设置和错误处理;你可以稍微修改一下代码,它应该可以自己运行。