8

ソケットに接続するPHPのコードがあります。書き込み中に断続的にパイプが壊れてしまいました。パイプに再度書き込むと、問題は解決するようです。私はそれから回復するために何が必要か(最も安全な方法)疑問に思っています。また、socket_writeに渡された完全な文字列を書き込まずに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。私はそれから回復するために何が必要か(最も安全な方法)疑問に思っています。

A:それはアプリケーションによって異なります。ソケットリスナーが接続を閉じているか、表示されていないソケットオプションを設定しました。これらのいずれかにどのように対処するかは、アプリケーションのセマンティクスによって異なります。

Q2。また、socket_writeに渡された完全な文字列を書き込まずにsocket_writeが返されるのではないかと思います。

A:はい。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 に答える