8

我在 PHP 中有一些连接到套接字的代码。在写信的时候,我的管道断断续续。如果再次写入管道,问题似乎消失了。我想知道需要什么(最安全的方法)才能从中恢复。我还想知道 socket_write 是否可以在不写入传递给它的完整字符串的情况下返回。这是我目前所拥有的。

function getSocket() {
  $socket = socket_create( AF_UNIX, SOCK_STREAM, 0 );
  if ( $socket === FALSE ) {
    throw new Exception(
      "socket_create failed: reason: " . socket_strerror( socket_last_error() ));
    }
  }

  $result = socket_connect($socket, $address);
  if ($result === false) {
    throw new Exception("socket_connect() failed.\nReason: ($result) " .
        socket_strerror(socket_last_error($socket)));
  }
  return $socket;
}

function writeSocket($stmt) {
  $tries = 0;
  $socket = getSocket();
  do {
    // Is is possible that socket_write may not write the full $stmt?
    // Do I need to keep rewriting until it's finished?
    $writeResult = socket_write( $socket, $stmt, strlen( $stmt ) );
    if ($writeResult === FALSE) {
      // Got  a broken pipe, What's the best way to re-establish and 
      // try to write again, do I need to call socket_shutdown?
      socket_close($socket);
      $socket = getSocket();
    }
    $tries++;
  } while ( $tries < MAX_SOCKET_TRIES && $writeResult ===  FALSE);
}
4

3 回答 3

2

Q1。我想知道需要什么(最安全的方法)才能从中恢复。

答:这取决于应用程序。套接字侦听器正在关闭连接,或者您设置了未向我们显示的套接字选项。你如何处理这些事情取决于应用程序的语义。

Q2。我还想知道 socket_write 是否可以在不写入传递给它的完整字符串的情况下返回。

答:是的。socket_write()可以在返回之前不写入字节、部分字节或所有字节。如果它返回的值大于零但小于输入的长度,则应调整偏移量(可能使用substr())。如果它返回零或更少,请检查socket_last_error()它是否可重试的线索。手册中介绍了这种扭曲。

于 2011-08-26T23:19:06.540 回答
0

您是否尝试过设置 SO_KEEPALIVE 或 SO_SNDTIMEO?您还可以在循环中测试缓冲区长度以查看是否已发送整个内容。

祝你好运,HTH,——乔

于 2011-08-26T19:16:35.443 回答
0

使用socket_set_nonblock()并修正你的while陈述:

$writeResult === FALSE应该$writeResult !== FALSE改为。

于 2011-08-26T22:54:07.983 回答