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

Java PHP FastCGI SocketException:读取数据时重置连接,java,php,fastcgi,Java,Php,Fastcgi,我正在尝试为我正在开发的Java Web服务器编写一个php cgi连接,但它并没有真正起作用 我目前正试图以这个php客户端为例编写一个fastcgi客户端 我设法让php cgi从我的请求中解析php文件。但是,当我尝试读取更多数据时,只有大约1/4的请求成功,然后失败: java.net.SocketException: Connection reset at java.net.SocketInputStream.read(Unknown Source) at java.n

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

我目前正试图以这个php客户端为例编写一个fastcgi客户端

我设法让php cgi从我的请求中解析php文件。但是,当我尝试读取更多数据时,只有大约1/4的请求成功,然后失败:

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)
这是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;
    }
}
package com.bit\u stab.fastcgi.client;
导入java.io.ByteArrayOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.net.Socket;
导入java.net.UnknownHostException;
导入java.util.Map;
导入java.util.Map.Entry;
公共类客户端
{
专用插座;
私有短请求ID=0b0;//TODO单例请求ID计数器
公共客户端(字符串主机,int端口)抛出UnknownHostException,IOException
{
套接字=新套接字(主机、端口);
}
公共短异步请求(映射参数、字符串内容)引发IOException
{
ByteArrayOutputStream paramBytes=新建ByteArrayOutputStream();
for(条目参数:params.entrySet())
write(nvpair(param.getKey(),param.getValue());
Packet beginRequest=新数据包((字节)1,请求ID,新字节[]{0,1,1,0,0,0,0});
数据包请求参数=新数据包((字节)4,请求ID,paramBytes.toByteArray());
数据包请求内容=新数据包((字节)5,请求ID,content.getBytes());
OutputStream=socket.getOutputStream();
stream.write(beginRequest.getBytes());
stream.write(requestParams.getBytes());
stream.write(requestContent.getBytes());
返回reqId++;
}
public void readResponse()引发IOException
{
InputStream=socket.getInputStream();
数据包响应=新数据包(流);
System.out.println(新字符串(response.getContent());
包p;
while((p=新数据包(流)).getType()!=3)
System.out.println(新字符串(p.getContent());
}
公共字节[]nvpair(字符串名称、字符串值)
{
尝试
{
int nl=name.length();
int vl=value.length();
ByteArrayOutputStream字节=新的ByteArrayOutputStream(nl+vl+10);
如果(nl<256)
字节。写入((字节)nl);
其他的
写入(新字节[]{b(nl>>24)、b(nl>>16)、b(nl>>8)、b(nl)});
中频(vl<256)
字节。写入((字节)vl);
其他的
写入(新字节[]{b(vl>>24)、b(vl>>16)、b(vl>>8)、b(vl)});
字节。写入(name.getBytes(“UTF-8”);
字节写入(value.getBytes(“UTF-8”);
返回bytes.toByteArray();
}
捕获(IOE异常)
{
e、 printStackTrace();
}
返回null;
}
公共字节b(int i)
{
返回(字节)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;
    }
}
package com.bit\u stab.fastcgi.client;
导入java.io.IOException;
导入java.io.InputStream;
公共类数据包
{
专用字节版本=1;
专用字节类型;
私有短请求ID;
专用字节paddingLength=0;
专用字节保留=0;
私有字节[]内容;
公共数据包(字节类型、短请求ID、字节…内容)
{
this.type=type;
this.requestId=requestId;
this.content=内容;
}
公共数据包(InputStream流)引发IOException
{
字节[]头=新字节[8];
流。读(头);
this.version=head[0];
this.type=头[1];
this.requestId=(短)((head[2]&0xFF)8);
b[3]=(字节)请求ID;
b[4]=(字节)(content.length>>8);
b[5]=(字节)content.length;
b[6]=填充长度;
b[7]=保留;
for(int i=0;i
我使用的是Java 8和windows.PHP.net中未经编辑的PHP5.6.1


这里出了什么问题,我该如何修复它?

我发现了问题所在,我发送的内容没有内容长度,它不喜欢这样

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