我正在使用套接字编写代理服务器,现在它似乎“工作”或多或少,但我现在遇到的问题是URL的图像没有回到浏览器,只有文本被退回......
这是代码:
//create inputstream to receive the web page from the host
BufferedInputStream inn = new BufferedInputStream(clientURLSocket.getInputStream());
//create outputstream to send the web page to the client
BufferedOutputStream outt = new BufferedOutputStream(clientSocket.getOutputStream());
URL u = new URL("http://"+url);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
byte[] chunk = new byte[1024];
int bytesRead;
InputStream stream = u.openStream();
while ((bytesRead = stream.read(chunk)) > 0) {
outputStream.write(chunk, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
outt.write(outputStream.toByteArray());
outt.flush();
也许ByteArrayOutputStream不好接收图片?
编辑(对于迟到的回复感到抱歉):
这是我的新代码:
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class Server {
public void startServer() {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
@Override
public void run() {
try {
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket clientSocket = serverSocket.accept();
Socket clientURLSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket));
clientProcessingPool.submit(new ClientTask(clientURLSocket));
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
private class ClientTask implements Runnable {
private Socket clientSocket;
private Socket clientURLSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
this.clientURLSocket = clientSocket;
}
@Override
public void run() {
try {
String url = null;
String curl = null;
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
String buffer;
while ((buffer = in.readLine()) != null) {
//System.out.println(buffer);
if(buffer.contains("GET"))
{
String[] splitText = buffer.split(" ");
curl = splitText[1];
System.out.println(curl);
}
if(buffer.contains("Host"))
{
//parse the host
url = buffer.replace("Host: ", "");
System.out.println(url);
}
if (buffer.isEmpty()) break;
}
//String IP = InetAddress.getByName(url).getHostAddress().toString();
//new socket to send the information over
clientURLSocket = new Socket(url, 80);
//get data from a URL
/* URL host = new URL("http://"+url);
URLConnection urlConnection = host.openConnection();
InputStream input = urlConnection.getInputStream();
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
input.close();*/
//create inputstream to receive the web page from the host
BufferedInputStream inn = new BufferedInputStream(clientURLSocket.getInputStream());
//create outputstream to send the web page to the client
BufferedOutputStream outt = new BufferedOutputStream(clientSocket.getOutputStream());
URL u = new URL(curl);
HttpURLConnection connection = null;
connection = (HttpURLConnection) u.openConnection();
connection.connect();
//ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
byte[] chunk = new byte[1024];
int bytesRead;
InputStream stream = connection.getInputStream();
while ((bytesRead = stream.read(chunk)) > 0) {
//outputStream.write(chunk, 0, bytesRead);
outt.write(chunk, 0, bytesRead);
outt.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
//outt.write(outputStream.toByteArray());
//outt.flush();
outt.close();
inn.close();
clientURLSocket.close();
/*
out.close();
in.close();
clientSocket.close();
*/
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
现在的问题是google.com工作正常(它显示所有图片和文字),但是例如youtube.com工作不正常(它也显示文字和图片,但网络没有完全显示并且它是无序的。)
我在这段代码中缺少什么?
顺便说一下,谢谢EJP& JB Nizet的帮助!
答案 0 :(得分:1)
您似乎不了解HTTP和HTML的工作原理。
当您使用浏览器转到http://google.com时,会发送第一个请求以获取HTML页面。服务器响应包含HTML标记,仅包含该标记。然后浏览器读取并解析此HTML标记,并看到它包含(例如)
<img src="logo.png"/>
因此它向URL http://google.com/logo.png发送新的HTTP请求。服务器发送包含徽标图像字节的响应。
如果您的代码只向http://google.com发送了一个请求,那么您将永远不会获得该徽标。
答案 1 :(得分:0)
HTTP代理比你在这里做的要简单得多。
您应该连接到CONNECT命令中指定的URL。不解析GET和HOST标头。一旦处理完CONNECT命令,剩下的就是来回复制字节。