Java PHP FastCGI SocketException:连接重置读取数据

时间:2014-11-29 19:25:54

标签: java php fastcgi

我试图为我正在开发的Java网络服务器编写一个php-cgi连接,但它并没有真正起作用。

我目前正在尝试使用此php客户端编写一个fastcgi客户端作为示例https://github.com/adoy/PHP-FastCGI-Client/blob/master/src/Adoy/FastCGI/Client.php

我设法让php-cgi解析我的请求中的php文件。但是,只有大约四分之一的请求有点成功,然后在我尝试阅读更多数据时失败:

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at com.bit_stab.fastcgi.client.Packet.<init>(Packet.java:26)
    at com.bit_stab.fastcgi.client.Client.readResponse(Client.java:51)
    at com.bit_stab.webdragonplugin.php.PHPPlugin.runPhpCgi(PHPPlugin.java:98)
    at com.bit_stab.webdragonplugin.php.PHPPlugin.main(PHPPlugin.java:42)

其余人只是侥幸:

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at com.bit_stab.fastcgi.client.Packet.<init>(Packet.java:37)
    at com.bit_stab.fastcgi.client.Client.readResponse(Client.java:46)
    at com.bit_stab.webdragonplugin.php.PHPPlugin.runPhpCgi(PHPPlugin.java:98)
    at com.bit_stab.webdragonplugin.php.PHPPlugin.main(PHPPlugin.java:42)

我目前正在使用php-cgi -b 127.0.0.1:8091从commandprompt运行php-cgi而且我正在使用此代码进行测试:

public static void main(String[] args)
{
    try
    {
        HashMap<String, String> map = new HashMap<String, String>();

        map.put( "DOCUMENT_ROOT" , "D:/Programma's/Eclipse/Workspaces/Java/HTTPWebServer/test root" );
        map.put( "SCRIPT_FILENAME" , "D:/Programma's/Eclipse/Workspaces/Java/HTTPWebServer/test root/index.php" );
        map.put( "SCRIPT_NAME" , "/index.php" );
        map.put( "DOCUMENT_URI" , "/index.php" );
        map.put( "REQUEST_METHOD" , "GET" );
        map.put( "SERVER_PROTOCOL" , "HTTP/1.1" );
        map.put( "REDIRECT_STATUS" , "200" );
        map.put( "PHP_SELF" , "/index.php" );
        map.put( "HOME" , "D:/Programma's/Eclipse/Workspaces/Java/HTTPWebServer/test root" );
        map.put( "FCGI_ROLE" , "RESPONDER" );
        map.put( "HTTP_CONNECTION" , "keep-alive" );


        Client c = new Client( "127.0.0.1" , 8090 );
        c.asyncRequest( map , "GET /index.php HTTP/1.1\r\nConnection: Keep-Alive\r\n\r\n" );
        c.readResponse();
    }
    catch( Exception e )
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

这是Client.java

package com.bit_stab.fastcgi.client;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Map.Entry;

public class Client
{
    private Socket socket;
    private short reqId = 0b0; //TODO singleton requestID counter

    public Client( String host, int port ) throws UnknownHostException, IOException
    {
        socket = new Socket( host, port );
    }

    public short asyncRequest( Map<String, String> params, String content ) throws IOException
    {
        ByteArrayOutputStream paramBytes = new ByteArrayOutputStream();

        for ( Entry<String, String> param: params.entrySet() )
            paramBytes.write( nvpair( param.getKey() , param.getValue() ) );

        Packet beginRequest = new Packet( (byte) 1, reqId, new byte[] { 0, 1, 1, 0, 0, 0, 0, 0 } );
        Packet requestParams = new Packet( (byte) 4, reqId, paramBytes.toByteArray() );
        Packet requestContent = new Packet( (byte) 5, reqId, content.getBytes() );

        OutputStream stream = socket.getOutputStream();

        stream.write( beginRequest.getBytes() );
        stream.write( requestParams.getBytes() );
        stream.write( requestContent.getBytes() );

        return reqId++;
    }

    public void readResponse() throws IOException
    {
        InputStream stream = socket.getInputStream();

        Packet response = new Packet( stream );

        System.out.println( new String( response.getContent() ) );

        Packet p;
        while ( ( p = new Packet( stream ) ).getType() != 3 )
            System.out.println( new String( p.getContent() ) );
    }

    public byte[] nvpair( String name, String value )
    {
        try
        {
            int nl = name.length();
            int vl = value.length();

            ByteArrayOutputStream bytes = new ByteArrayOutputStream( nl + vl + 10 );

            if ( nl < 256 )
                bytes.write( (byte) nl );
            else
                bytes.write( new byte[] { b( nl >> 24 ), b( nl >> 16 ), b( nl >> 8 ), b( nl ) } );

            if ( vl < 256 )
                bytes.write( (byte) vl );
            else
                bytes.write( new byte[] { b( vl >> 24 ), b( vl >> 16 ), b( vl >> 8 ), b( vl ) } );

            bytes.write( name.getBytes( "UTF-8" ) );
            bytes.write( value.getBytes( "UTF-8" ) );

            return bytes.toByteArray();
        }
        catch( IOException e )
        {
            e.printStackTrace();
        }
        return null;
    }

    public byte b( int i )
    {
        return (byte) i;
    }
}

这是Packet.java

package com.bit_stab.fastcgi.client;

import java.io.IOException;
import java.io.InputStream;

public class Packet
{
    private byte version = 1;
    private byte type;
    private short requestId;
    private byte paddingLength = 0;
    private byte reserved = 0;

    private byte[] content;

    public Packet( byte type, short requestId, byte... content )
    {
        this.type = type;
        this.requestId = requestId;
        this.content = content;
    }

    public Packet( InputStream stream ) throws IOException
    {
        byte[] head = new byte[8];
        stream.read( head );

        this.version = head[0];
        this.type = head[1];
        this.requestId = (short)( ( ( head[2] & 0xFF ) << 8 ) | ( head[3] & 0xFF ) );
        int contentLength =     ( ( ( head[4] & 0xFF ) << 8 ) | ( head[5] & 0xFF ) );
        this.paddingLength = head[6];
        this.reserved = head[7];

        this.content = new byte[contentLength];

        stream.read( content );
        stream.skip( paddingLength & 0xFF );
    }

    public byte getType()
    {
        return type;
    }

    public short getId()
    {
        return requestId;
    }

    public byte[] getContent()
    {
        return content;
    }

    public byte[] getBytes()
    {
        byte[] b = new byte[8 + content.length];

        b[0] = version;
        b[1] = type;
        b[2] = (byte) ( requestId >> 8 );
        b[3] = (byte) requestId;
        b[4] = (byte) ( content.length >> 8 );
        b[5] = (byte) content.length;
        b[6] = paddingLength;
        b[7] = reserved;

        for ( int i = 0; i < content.length; i++ )
            b[i + 8] = content[i];

        return b;
    }
}

我在windows.php.net上使用Java 8和未经编辑的PHP 5.6.1

这里出了什么问题,我该如何解决?

1 个答案:

答案 0 :(得分:2)

我发现它是什么,我发送的内容没有内容长度而且它不是那样的。