Простой Java HTTP-прокси с сокетами застревает без сообщения об ошибке - PullRequest
2 голосов
/ 27 ноября 2010

Я пытаюсь заставить простой многопоточный прокси работать на Java.Однако мне не удается отобразить веб-страницу в моем браузере, после первого запроса GET и ответа с веб-страницы программа просто зависла (как вы можете видеть из моего кода, я печатаю все, что у меня есть)стандартный вывод для отладки, и там я вижу исходный код веб-страницы, однако после распечатки «После записи клиента» ничего не происходит (без исключения, просто ничего ...)).

import java.net.*;
import java.util.*;

import java.io.*;

public class Proxy
{   

public static void main(String[] args)
{
    try
    {
        ServerSocket listensocket = new ServerSocket(Integer.valueOf(args[0]));
        while(true)
        {
            System.out.println("wait");
            Socket acceptsocket = listensocket.accept(); // blocking call until it receives a connection
            myThread thr = new myThread(acceptsocket);
            thr.start();
        }

    }
    catch(IOException e)
    {
        System.err.println(">>>>" + e.getMessage() );
        e.printStackTrace();
    }

}

static class myThread extends Thread
{
    Socket acceptsocket;
    int host, port;

    String  url;

    myThread(Socket acceptsocket)
    {
        this.acceptsocket=acceptsocket;
    }
    public void run() {
        try
        {
            System.out.println("hello");

             Socket client = acceptsocket;
            //client.setSoTimeout(100);
            InputStream clientIn = client.getInputStream();
            //BufferedInputStream clientIn=new BufferedInputStream(clientis);
            OutputStream clientOut = client.getOutputStream();
            System.out.println("hello");

            String clientRequest = readStuffFromClient(clientIn); // parses the host and what else you need
            System.out.print("Client request: -----\n"+clientRequest);

            Socket server;
            server = new Socket("xxxxxxxxxxxxx"  , 80);


            InputStream serverIn = server.getInputStream();
            //BufferedInputStream serverIn=new BufferedInputStream(serveris);
            OutputStream serverOut = server.getOutputStream();


            serverOut.write(clientRequest.getBytes());
            serverOut.flush();

            String serverResponse = readStuffFromClient(serverIn);

            System.out.print("Server Response: -----\n"+serverResponse);

            clientOut.write(serverResponse.getBytes());
            clientOut.flush();
            System.out.println("After Client Write");

            clientIn.close();
            clientOut.close();
            serverIn.close();
            serverOut.close();
            server.close();
            client.close();


        }
        catch(Exception e)
        {
            System.out.println(e);
        }
    }
    private String readStuffFromClient(InputStream clientdata)
    {
        ByteArrayOutputStream response = new ByteArrayOutputStream();
        StringBuffer request=new StringBuffer(8192);
        int i, httpstart,n=-1 ;
        byte[] buffer = new byte[8192];

        System.out.println("beforetry");

        try 
        {

            while((n = clientdata.read(buffer))!=-1)
            {
            System.out.println("before");
            response.write(buffer,0,n);
            //response.flush();
              }
              request=new StringBuffer(response.toString());
              /*System.out.println("new:"+n+" "+ request.toString());
              System.out.println("End client data");*/

        }    
        catch (Exception e) 
        {
            System.out.println("here");
            System.out.println(e);
            e.printStackTrace();
            i = -1;
        }




            System.out.println("End manipulation method");
            return request.toString();
        }
}



}

(этоэто урезанный не работающий пример моей программы, из комментариев видно, что я уже пытался использовать BufferedInputStream).В общем, эта программа очень не отвечает даже на первый запрос GET из браузера.Когда я читаю данные клиента только один раз (не в цикле), я иду немного дальше, например, получаю больше пар GET / Response, но в какой-то момент программа все еще застревает.

Почему-то я думаю, что либо яЭто настоящая тривиальная ошибка, которую я просто не вижу, или программа должна работать, но просто не по какой-либо реальной причине.

Любая помощь приветствуется, спасибо заранее!

Ответы [ 3 ]

0 голосов
/ 27 ноября 2010

Это заставит его работать:

Он проверит, есть ли больше данных для чтения

Тем не менее, важно использовать BufferedIS, потому что я думаю, что ByteArrayIS не реализует доступный метод.

 BufferedInputStream bis = new BufferedInputStream(clientdata);
            System.out.println("beforetry");

            try {
                while(bis.available() > 0){
                    n = bis.read(buffer);
                    response.write(buffer, 0, n);
                }
0 голосов
/ 29 ноября 2010

Вам нужны два потока: один для чтения с клиента и записи на сервер, а другой - для каждого принятого сокета.Есть еще одна тонкость: когда вы читаете EOS в одном направлении, отключите противоположный сокет для выхода, а затем, если входной сокет для этого потока уже отключен для выхода, закройте оба сокета.В обоих случаях выйдите из потока, который читает EOS.

0 голосов
/ 27 ноября 2010

Попробуйте сначала получить OutputStream, а затем InputStream!

InputStream clientIn = client.getInputStream();
OutputStream clientOut = client.getOutputStream();

изменить на:

OutputStream clientOut = client.getOutputStream();
InputStream clientIn = client.getInputStream();
...