【问题标题】:Android proxy using sockets使用套接字的 Android 代理
【发布时间】:2013-06-03 03:09:48
【问题描述】:

我正在尝试在 Android 中创建代理,我必须使用套接字。我已经阅读了许多教程并提出了以下代码。不幸的是,浏览器似乎没有得到任何数据,一段时间后它显示标准网页,说网页不可用。可能是什么原因?感谢您的帮助。

        ServerSocket serverSocket = null;
            try {
                serverSocket = new ServerSocket(9902, 0, InetAddress.getByName("localhost"));
            } catch (Exception e) {
                e.printStackTrace();
            }
    if (serverSocket != null) {
                while (!Thread.currentThread().isInterrupted()) {
                    try {
                        Socket socket = serverSocket.accept();
                        new Thread(new RunnableToReadSocketData(socket)).start();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

private class RunnableToReadSocketData implements Runnable {
        private final Socket clientSocket;

        public RunnableToReadSocketData(Socket socket) {
            this.clientSocket = socket;
        }

        @Override
        public void run() {
            Socket serverSocket = null;
            try {
                InputStream streamFromClient = clientSocket.getInputStream();
                PrintWriter streamToClient = new PrintWriter(clientSocket.getOutputStream());

                StringWriter writer = new StringWriter();
                IOUtils.copy(streamFromClient, writer);
                String requestString = writer.toString();

                int firstSpace = requestString.indexOf(" ");
                int secondSpace = requestString.indexOf(" ", ++firstSpace);

                String url = requestString.substring(firstSpace, secondSpace);
                Uri uri = Uri.parse(url);
                String urlWithoutProtocol = uri.getHost();

                System.out.println("==============Reading Socket==============\n" + clientSocket.toString() + "\n" + requestString);

                serverSocket = new Socket(urlWithoutProtocol, 80);

                PrintWriter streamToServer = new PrintWriter(serverSocket.getOutputStream(), true);
                streamToServer.write(requestString);
                streamToServer.flush();

                InputStream streamFromServer = serverSocket.getInputStream();
                StringWriter writerResponse = new StringWriter();
                IOUtils.copy(streamFromServer, writerResponse);
                String responseString = writerResponse.toString();

                System.out.println("==============RECEIVED==============\n" + serverSocket.toString() + "\n" + responseString);

                streamToClient.write(responseString);
                streamToClient.flush();

                streamToClient.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (serverSocket != null) {
                        serverSocket.close();
                    }

                    if (clientSocket != null) {
                        clientSocket.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

【问题讨论】:

    标签: android sockets proxy stream apache-commons


    【解决方案1】:

    我同意前面的。

    一般原则是:

    • 客户端连接
    • 开始阅读线程
    • 接收请求
    • 解析目的地
    • 打开到目标的套接字
    • 转发请求

    • 对于目标套接字上的每次读取,在客户端套接字上执行写入

    • 对于客户端套接字上的每个读取,在目标套接字上执行写入
    • 如果任一套接字关闭(错误),则关闭另一个

    所以,两个 InputStream's,两个 OutputStreams,只是在它们之间传送数据。

    【讨论】:

    • 您描述的 General principal 保留在上面的代码中。如果您:获取整个请求,将其发送到服务器,获取整个响应,将其传递给客户端,它将同样有效。
    【解决方案2】:

    你做错了。处理完 CONNECT 命令后,您需要启动两个线程以通过连接复制字节,每个方向一个。在发送任何内容之前不要尝试阅读整个请求;同上响应。只需在收到字节时复制它们。

    当您在一个套接字上读取 EOS 时,关闭另一个套接字以进行输出并退出该线程。如果您已经关闭了从中读取 EOS 的套接字,请关闭两者并退出线程。你需要这个,以防任何一端关闭,以正确传播它。

    【讨论】:

    • 你不需要2个线程来读写数据。一个就足够了。 sn-p 上面缺少的是正确的请求/响应结束。我在请求和响应的末尾以及请求/响应标头之间添加了“\r”和“\n”的组合,因为它们在处理时被剪切了。这导致消息成功传递。
    猜你喜欢
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2022-01-20
    相关资源
    最近更新 更多