我试图在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();
}
}
}
}
你这样做不对。在处理CONNECT命令之后,需要启动两个线程在连接上复制字节,每个方向一个。在发送任何东西之前,不要试图阅读整个请求;回应也是如此。当你收到字节时就复制。
当你在一个套接字上读取EOS时,关闭另一个套接字以输出并退出该线程。如果您已经关闭了从其中读取EOS的套接字,请关闭这两个套接字并退出线程。您需要在任何一端关闭的情况下,正确地传播它。
我同意前面的观点。
一般原则是:
- 客户机连接
- 开始读取线程
- 接收请求 <
- 解析目的地/gh>
- 打开套接字到目的地
-
请求转发
对于目标套接字上的每个Read,在客户端套接字上做一个写操作
- 对于客户端套接字上的每个Read,在目标套接字上做一个写操作
- 如果其中一个socket关闭(错误),关闭另一个
所以,两个InputStream,两个outputstream,只是在它们之间传递数据。