代理服务器无法将响应发送回客户端

时间:2018-12-20 13:09:05

标签: java multithreading sockets tcp-ip http-proxy

我正在使用Java创建代理服务器,而我的客户端和服务器都是用NodeJS编写的。由于客户端可以发送多个请求,因此我正在为每个客户端请求向代理服务器创建线程。现在,当我从服务器获得响应(整数值)时,我想将相同的数据从代理服务器发送回客户端。但是我的代理服务器无法执行此操作。

客户期望在100毫秒内做出响应。所以我设置了连接并读取超时属性。如果在这段时间内没有收到响应,那么我想用整数0响应客户端。

SocketServer.java

private int portNo;
private ServerSocket serverSocket = null;

public SocketServer(int portNo) {
    this.portNo = portNo;
    try {
        serverSocket = new ServerSocket(this.portNo);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void runServer() {
    while(true) {
        try {
            Socket clientSocket = serverSocket.accept();
            new Thread(new Task(clientSocket)).start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public static void main(String args[]) {
    SocketServer socketServer = new SocketServer(3000);
    socketServer.runServer();
}

Task.java

public class Task implements Runnable {

    Socket socket = null;

    public Task(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String dataFromClient = in.readLine(); // this is the url from client
            String partOfLink = dataFromClient.substring(5, 9);

            URL url = new URL("http://localhost:3001/" + partOfLink);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setDoOutput(true);
            conn.setConnectTimeout(80);
            conn.setReadTimeout(80);

            // Get the response
            BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = rd.readLine()) != null) {
                out.write(line);
            }

        } catch (IOException e) {
            //e.printStackTrace();
            try {
                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                out.write(0);
            } catch (IOException e1) {
                e1.printStackTrace();
            }   
        }
    }
}

1 个答案:

答案 0 :(得分:2)

您当前遇到的特定问题可能是客户端收到零并说:“这不是完整的HTTP答复,我希望获得完整的HTTP答复,因此必将有更多数据来”,因此它等待更多数据

由于客户端仅讲HTTP,并且在超时情况下您没有将HTTP发送给客户端,所以为什么希望它能正常工作?

即使成功,您实际上也没有这样做!您已将HTTP解码器附加到出站连接,并将 decoded 输出中继到客户端。但是客户端希望使用 raw HTTP。

有很多方法可以咬你。假设代理响应标头指示分块编码。您或者需要修改这些标头,或者也需要使用分块编码将数据发送到客户端,因为接收代理响应的代码会解码分块编码。代码在哪里?

您需要正确处理HTTP连接持久性。您需要检测客户端是否支持它以及代理的回复是否兼容,以了解代理回复后如何处理客户端连接。你应该关闭它吗?您是否应该尝试在同一连接上收到其他答复?这取决于几个因素-正确执行此决策的代码在哪里?

您的代码还有很多其他问题。您应该查看适用于现有HTTP代理的代码,并了解其工作方式。要使真正的HTTP代理正常工作,您必须解决很多问题,而您尚未解决这些问题。

有些可能的骇客可能会采用这种方法,使其看起来足够有效,以至于您可以将其照做。但是,如果这是必须可靠的重要应用程序,那么这是错误的方法。 HTTP代理是一件大而复杂的事情。这段代码不是一个。

寻找可以使用的实际HTTP代理的最简单代码。阅读HTTP规范,并仔细查看代理要求。这是一个雷区,您确实应该从已知可以正常工作的HTTP代理开始,并根据需要对其进行修改。