带套接字的简单Java HTTP代理卡在没有错误消息的情况下卡住

时间:2010-11-27 07:58:56

标签: java http sockets proxy webserver

我正在尝试使用简单的多线程代理在Java中工作。但是我没有设法让网页显示在我的浏览器中,在第一个GET请求和网页响应之后,程序就被卡住了(从我的代码中可以看出,我正在打印所有的内容)用于调试的stdout,在那里我看到了网页的源代码,但是在打印出“After Client Write”之后,没有任何反应(没有例外,只是没有...)。

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请求,该程序也没有响应。当我只读取clientdata一次(不是循环)时,我会更进一步,例如获得更多GET / Response对,但在某些时候程序仍然卡住了。

不知怎的,我认为要么是一个我无法看到的真正的微不足道的错误,要么程序应该有效,但根本没有真正的原因。

感谢任何帮助,提前谢谢!

3 个答案:

答案 0 :(得分:0)

您需要两个线程:一个用于从客户端读取并写入服务器,另一个用于执行相反的操作,用于每个接受的套接字。还有一个细微之处:当你从一个方向读取EOS时,关闭相反的套接字输出,然后如果该线程的输入套接字已经关闭输出,则关闭两个套接字。在这两种情况下都退出读取EOS的线程。

答案 1 :(得分:-1)

首先尝试获取OutputStream然后输入InputStream!

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

将其更改为:

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

答案 2 :(得分:-1)

这将使其有效:

它将检查是否有更多数据可供阅读

但是,使用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);
                }