【问题标题】:get socket error string when async connect fails异步连接失败时获取套接字错误字符串
【发布时间】:2010-07-26 08:52:29
【问题描述】:

如果像下面这样的异步连接失败,任何人都知道是否有可能检索一些错误信息(如 C 中的 getsockopt SO_ERROR) 顺便说一句:我没有使用套接字扩展,因为流提供了一个 ssl 包装器

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

谢谢

【问题讨论】:

    标签: php stream asynchronous connect


    【解决方案1】:

    我遇到了与描述相同的问题。我找到了一些解决方法:

    我将每个“流”包装在 Stream 类中并设置超时属性。在调用 connect 之前,我会生成超时时间的时间戳。然后我在Manager 类中有一个循环,它调用stream_select()

    成功的连接被放置在$write 数组中。我在循环底部有另一个调用$stream-&gt;checkTimeout()。其中有一个stream_select() 调用,为tv_sectv_usec 设置了0。如果 $this->conn 没有出现在$write 中,我认为它已经超时。

    【讨论】:

      【解决方案2】:

      据我了解,流函数中的错误应该会生成 PHP 警告消息。我认为唯一的方法是使用 set_error_handler() 捕获这些并在那里处理它们。

      【讨论】:

        【解决方案3】:

        我也遇到了这个问题。我找到的解决方案是使用stream_socket_get_name。如果您希望这一切都包含在一个不错的图书馆结帐http://drupal.org/project/httprl 中。它仍然需要drupal,但主要用于设置和错误处理;你可以稍微修改一下代码,它应该可以自己运行了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-11-24
          • 1970-01-01
          • 1970-01-01
          • 2021-08-14
          • 2014-07-18
          • 2013-07-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多