Java 代理服务器-编码错误

Java 代理服务器-编码错误,java,proxy,serversocket,Java,Proxy,Serversocket,我正在尝试编写简单的代理服务器(处理GET请求)。我编写了以下代码: public void handle(Socket socket) throws IOException, URISyntaxException { /* CLIENT -> SERVER */ Scanner clientInputScanner = new Scanner(socket.getInputStream()); List<String> clientHeaders

我正在尝试编写简单的代理服务器(处理GET请求)。我编写了以下代码:

public void handle(Socket socket) throws IOException, URISyntaxException {

    /* CLIENT -> SERVER */
    Scanner clientInputScanner = new Scanner(socket.getInputStream());

    List<String> clientHeaders = new ArrayList<String>();

    String line;
    String targetUrl = null;

    boolean firstLine = true;

    while ((line = clientInputScanner.nextLine()) != null) {

        if (line.length() <= 0) {
            break;
        }

        if (firstLine) {

            String[] tokens = line.split(" ");
            targetUrl = tokens[1];

            line = tokens[0] + " " + this.extractPath(tokens[1]) + " " + tokens[2];

            firstLine = false;
        }

        clientHeaders.add(line);
    }


    Socket server = new Socket(this.extractHostName(targetUrl), 80);
    PrintWriter serverPrint = new PrintWriter(server.getOutputStream());

    for (String header: clientHeaders) {
        serverPrint.println(header);
    }

    serverPrint.println("");
    serverPrint.flush();

    /* SERVER -> CLIENT */
    Scanner serverScanner = new Scanner(server.getInputStream());
    PrintWriter clientPrinter = new PrintWriter(socket.getOutputStream());

    List<String> serverHeaders = new ArrayList<String>();
    int serverContentLength = 0;

    while ((line = serverScanner.nextLine()) != null) {

        if (line.length() <= 0) {
            break;
        }

        serverHeaders.add(line);

        if (line.startsWith("Content-Length: ")) {
            // content-length
            int index = line.indexOf(':') + 1;
            String len = line.substring(index).trim();
            serverContentLength = Integer.parseInt(len);
        }
    }

    for (String header: serverHeaders) {
        clientPrinter.println(header);
    }

    clientPrinter.println("");
    clientPrinter.flush();

    if (serverContentLength > 0) {

        InputStream serverReader = server.getInputStream();
        OutputStream clientWriter = socket.getOutputStream();

        byte[] buff = new byte[1024];
        int bytesRead;
        int count = 0;

        while ((bytesRead = serverReader.read(buff)) != -1) {

            if (count == serverContentLength) {
                break;
            }

            clientWriter.write(buff, 0, bytesRead);
            clientWriter.flush();
            count += bytesRead;
        }

        clientWriter.close();
        serverReader.close();
    }

    clientInputScanner.close();
}
public void句柄(套接字)抛出IOException、URISyntaxException{
/*客户端->服务器*/
Scanner clientInputScanner=新扫描仪(socket.getInputStream());
List clientHeaders=new ArrayList();
弦线;
字符串targetUrl=null;
布尔第一行=真;
而((line=clientInputScanner.nextLine())!=null){
if(line.length()客户端*/
Scanner服务器Scanner=新扫描仪(server.getInputStream());
PrintWriter clientPrinter=新的PrintWriter(socket.getOutputStream());
List serverHeaders=new ArrayList();
int serverContentLength=0;
而((line=serverScanner.nextLine())!=null){
if(line.length()0){
InputStream serverReader=server.getInputStream();
OutputStream clientWriter=socket.getOutputStream();
字节[]buff=新字节[1024];
int字节读取;
整数计数=0;
while((bytesRead=serverReader.read(buff))!=-1){
if(count==serverContentLength){
打破
}
clientWriter.write(buff,0,bytesRead);
clientWriter.flush();
计数+=字节读取;
}
clientWriter.close();
serverReader.close();
}
clientInputScanner.close();
}
问题是编码-webbrowser无法理解正文请求(它显示奇怪的字符)。我正在传递原始字节(没有将其解释为字符),因此不知道会出现什么错误。内容类型标头传递正确(编码良好)


注意:这只是POC的代码,我只需要让它工作。因此,代码样式很难看:)

扫描器将读取整个缓冲区的数据。它不会在当前行的末尾停止读取。因此扫描器将已经从您的身体中读取了数据-只要您这样做
InputStream serverReader=server.getInputStream();
,来自身体的部分(或全部)数据已被扫描仪使用

您必须坚持使用一个从套接字读取的类,并且由于您想要读取二进制数据,因此必须是一个普通的
InputStream
BufferedReader
Scanner
不能使用,因为它们将读取超出行尾的缓冲区

您可以在
InputStream
上实现自己的readLine方法-只要看到行的结尾就停止读取,其余的数据仍将作为身体的一部分在那里供您使用


这可能解释了奇怪的字符,也可能解释不了奇怪的字符-我们需要知道您发送的是什么数据,以及您如何查看数据才能确定。

我发送了简单的GET to StackOverflow。您可能是对的,当我将全部改为InputStream读取时(不分为标题和正文部分)它起作用了。我想这可能是一个原因,但我不确定。谢谢!