写入套接字并处理损坏的管道

发布于 2024-12-01 18:36:29 字数 1207 浏览 4 评论 0原文

我有一些 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);
}

I have some code in PHP that connects to a socket. I've been getting a broken pipe intermittently while writing to it. The problems seems to go away if write to the pipe again. I'm wondering what's required (the safest way) to recover from it. I'm also wondering whether socket_write may return without writing the full string that was passed into it. Here's what I have currently.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

×纯※雪 2024-12-08 18:36:29

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

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

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

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

Q1. I'm wondering what's required (the safest way) to recover from it.

A: That depends on the application. The socket listener is closing the connection, or you've set socket options that you're not showing us. How you deal with either of these things depends on the semantics of the application.

Q2. I'm also wondering whether socket_write may return without writing the full string that was passed into it.

A: Yes. socket_write() can write no bytes, some of the bytes, or all of the bytes before returning. If it returns a value greater than zero but less than the length of the input, you should adjust offsets (perhaps using substr()). If it returns zero or less, inspect socket_last_error() for clues as to whether it is retry-able. This contortion is covered in the manual.

掩饰不了的爱 2024-12-08 18:36:29

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

祝你好运和 HTH,
——乔

Have you tried setting SO_KEEPALIVE or SO_SNDTIMEO? You might also test in your loop for the buffer length to see if the whole thing has been sent.

Good luck and HTH,
-- Joe

青春如此纠结 2024-12-08 18:36:29

使用 socket_set_nonblock() 并修复您的 while 语句:

$writeResult === FALSE 应为 $writeResult !== FALSE 代替。

Use socket_set_nonblock() and fix your while statement:

$writeResult === FALSE should be $writeResult !== FALSE instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文