Java 代理服务器-编码错误
我正在尝试编写简单的代理服务器(处理GET请求)。我编写了以下代码:Java 代理服务器-编码错误,java,proxy,serversocket,Java,Proxy,Serversocket,我正在尝试编写简单的代理服务器(处理GET请求)。我编写了以下代码: public void handle(Socket socket) throws IOException, URISyntaxException { /* CLIENT -> SERVER */ Scanner clientInputScanner = new Scanner(socket.getInputStream()); List<String> clientHeaders
public void handle(Socket socket) throws IOException, URISyntaxException {
/* CLIENT -> SERVER */
Scanner clientInputScanner = new Scanner(socket.getInputStream());
List<String> clientHeaders = new ArrayList<String>();
String line;
String targetUrl = null;
boolean firstLine = true;
while ((line = clientInputScanner.nextLine()) != null) {
if (line.length() <= 0) {
break;
}
if (firstLine) {
String[] tokens = line.split(" ");
targetUrl = tokens[1];
line = tokens[0] + " " + this.extractPath(tokens[1]) + " " + tokens[2];
firstLine = false;
}
clientHeaders.add(line);
}
Socket server = new Socket(this.extractHostName(targetUrl), 80);
PrintWriter serverPrint = new PrintWriter(server.getOutputStream());
for (String header: clientHeaders) {
serverPrint.println(header);
}
serverPrint.println("");
serverPrint.flush();
/* SERVER -> CLIENT */
Scanner serverScanner = new Scanner(server.getInputStream());
PrintWriter clientPrinter = new PrintWriter(socket.getOutputStream());
List<String> serverHeaders = new ArrayList<String>();
int serverContentLength = 0;
while ((line = serverScanner.nextLine()) != null) {
if (line.length() <= 0) {
break;
}
serverHeaders.add(line);
if (line.startsWith("Content-Length: ")) {
// content-length
int index = line.indexOf(':') + 1;
String len = line.substring(index).trim();
serverContentLength = Integer.parseInt(len);
}
}
for (String header: serverHeaders) {
clientPrinter.println(header);
}
clientPrinter.println("");
clientPrinter.flush();
if (serverContentLength > 0) {
InputStream serverReader = server.getInputStream();
OutputStream clientWriter = socket.getOutputStream();
byte[] buff = new byte[1024];
int bytesRead;
int count = 0;
while ((bytesRead = serverReader.read(buff)) != -1) {
if (count == serverContentLength) {
break;
}
clientWriter.write(buff, 0, bytesRead);
clientWriter.flush();
count += bytesRead;
}
clientWriter.close();
serverReader.close();
}
clientInputScanner.close();
}
public void句柄(套接字)抛出IOException、URISyntaxException{
/*客户端->服务器*/
Scanner clientInputScanner=新扫描仪(socket.getInputStream());
List clientHeaders=new ArrayList();
弦线;
字符串targetUrl=null;
布尔第一行=真;
而((line=clientInputScanner.nextLine())!=null){
if(line.length()客户端*/
Scanner服务器Scanner=新扫描仪(server.getInputStream());
PrintWriter clientPrinter=新的PrintWriter(socket.getOutputStream());
List serverHeaders=new ArrayList();
int serverContentLength=0;
而((line=serverScanner.nextLine())!=null){
if(line.length()0){
InputStream serverReader=server.getInputStream();
OutputStream clientWriter=socket.getOutputStream();
字节[]buff=新字节[1024];
int字节读取;
整数计数=0;
while((bytesRead=serverReader.read(buff))!=-1){
if(count==serverContentLength){
打破
}
clientWriter.write(buff,0,bytesRead);
clientWriter.flush();
计数+=字节读取;
}
clientWriter.close();
serverReader.close();
}
clientInputScanner.close();
}
问题是编码-webbrowser无法理解正文请求(它显示奇怪的字符)。我正在传递原始字节(没有将其解释为字符),因此不知道会出现什么错误。内容类型标头传递正确(编码良好)
注意:这只是POC的代码,我只需要让它工作。因此,代码样式很难看:)扫描器将读取整个缓冲区的数据。它不会在当前行的末尾停止读取。因此扫描器将已经从您的身体中读取了数据-只要您这样做
InputStream serverReader=server.getInputStream();
,来自身体的部分(或全部)数据已被扫描仪使用
您必须坚持使用一个从套接字读取的类,并且由于您想要读取二进制数据,因此必须是一个普通的InputStream
BufferedReader
和Scanner
不能使用,因为它们将读取超出行尾的缓冲区
您可以在InputStream
上实现自己的readLine方法-只要看到行的结尾就停止读取,其余的数据仍将作为身体的一部分在那里供您使用
这可能解释了奇怪的字符,也可能解释不了奇怪的字符-我们需要知道您发送的是什么数据,以及您如何查看数据才能确定。我发送了简单的GET to StackOverflow。您可能是对的,当我将全部改为InputStream读取时(不分为标题和正文部分)它起作用了。我想这可能是一个原因,但我不确定。谢谢!