连接重置由同行

时间:2014-10-22 10:54:42

标签: java php client-server

它是关于客户端(PHP)服务器(Java)环境的。当php请求一个大约40k个字符长的网页时,我在Java端(out.flush())得到以下异常。我已经多次使用这种架构而没有任何例外。结果,显示了一个页面,但并不完全。

java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)
at sun.nio.cs.StreamEncoder.write(Unknown Source)
at java.io.OutputStreamWriter.write(Unknown Source)
at java.io.BufferedWriter.flushBuffer(Unknown Source)
at java.io.BufferedWriter.flush(Unknown Source)
at sitodove.core.net.Connection.writeMessage(Connection.java:79)
at sitodove.core.net.FrontendConnection.run(FrontendConnection.java:149)

以下是发送特定字符串作为对每个PHP请求的响应的Java代码

    public void writeMessage(String message) throws IOException
{
    Logger.log("writeMessage, Valore in entrata: "+message);
    int messageLength=message.length();
    String startingNumber=""+messageLength;
    StringBuffer prefix=new StringBuffer(""+messageLength);
    for(int i=0;i<PROTOCOL_PREFIX_LENGTH-startingNumber.length();i++)
        prefix.insert(0, "0");
    prefix.append(message);
    Logger.log("writeMessage, Valore in uscita: "+prefix);
    out.write(prefix.toString());
    out.flush();
    Logger.log("DATI INVIATI");
}

以下是发出请求并从Java服务器读取响应的PHP代码

$SEPARATOR='!!@!!';
function communicate($remoteServer, $remotePort, $outText) 
{
    $outTextLength = strlen($outText);
    $lengthPaddedPrefix = str_pad($outTextLength, 8, "0", STR_PAD_LEFT);
    $message = $lengthPaddedPrefix.$outText;

    $socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket");
    socket_connect($socket, $remoteServer, $remotePort) or  header( 'Location: /maintenance/' );

    socket_write($socket, $message, strlen($message)) or  header( 'Location: /maintenance/' );
    //echo 'COMUNICATO';
    $response = socket_read($socket, 20000000) or  header( 'Location: /maintenance/' );

    socket_close($socket);

    if (strpos($response, "JAVA is not responding") !== false) {
            die("Site is down for maintenance");
    }
    return substr($response, 8);
}

$coreanswer=$coreanswer=communicate('localhost', 6527, "showreport".$SEPARATOR.$_GET['uid'].$SEPARATOR.$_GET['wid'].$SEPARATOR.$_GET['getime'].$SEPARATOR.$_GET['rct']);
echo $coreanswer;

1 个答案:

答案 0 :(得分:1)

&#34;由同行重置连接&#34;表示您尝试写入已关闭的套接字。 socket_read函数不会一次性读取套接字中的所有数据,最终在服务器完成所有内容之前关闭套接字。您需要一个循环来读取所有内容,并且还准备好在服务器中处理异常,因为客户端行为不正确。

例如:

$data = "";
do {
    $data = socket_read($socket, 20000000);
    if ($data === FALSE) {
        // socket read error
        header( 'Location: /maintenance/' );
        break;
    }
    $response .= $data;
} while ($data);