我用Java创建了一个代理服务器,(参见下面的代码),问题是,我从Web服务器得到响应但是我的客户端代理处理客户端之间的连接(浏览器)和代理服务器端创建套接字后的Web服务器。服务器端创建客户端并发送请求和套接字,然后在新线程中处理。 我有几个问题:
第一个代码属于代理的客户端第二个代码部分属于代理服务器端
使用字符串是否可以,或者在从流中发送和接收时是否应该使用某种类型的字节数组?
为什么浏览器没有从代理接收任何内容?因为我可以从控制台打印出来,但是当写入流时,浏览器中没有任何反应。
另外,为什么我需要在浏览器中点击“输入”两次才能让代理做出反应?
public class Client implements Runnable {
private String request;
private String response;
private Socket browserSocket;
public Client(String request, Socket browserSocket) {
this.request = request;
this.response = "";
this.browserSocket = browserSocket;
}
@Override
public void run() {
/* Send request to web server and get the response. */
this.request = Client.modifyHttpHeader("Connection", "close", this.request);
String hostName = Client.getHttpHeader("Host", this.request);
if (!hostName.isEmpty()) {
try {
/* Send request to the web-server. */
Socket socket = new Socket(hostName, 80);
OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());
PrintWriter pw = new PrintWriter(osw);
pw.write(this.request);
pw.flush();
System.out.println("---S:REQUEST---");
System.out.println(this.request);
System.out.println("---S:REQUEST---");
/* Receive the response from the web-server. */
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String response = "";
int tmpData;
while ((tmpData = br.read()) != -1) {
response += (char)tmpData;
}
this.response = response;
socket.close(); /* Close the socket between client-side and web-server. */
/* Send the response back to the browser. */
OutputStreamWriter oswbrowser = new OutputStreamWriter(this.browserSocket.getOutputStream());
PrintWriter pwBrowser = new PrintWriter(oswbrowser);
pwBrowser.write(this.response);
pwBrowser.flush();
pwBrowser.close();
this.browserSocket.close(); /* Close the socket between client-side and browser. */
System.out.println("---C:RESPONSE---");
System.out.println(this.response);
System.out.println("---C:RESPONSE---");
} catch (Exception e) {
System.err.println(e.getMessage());
e.printStackTrace();
}
}
}
public String getHttpResponse() {
return this.response;
}
/**
*
* @param header
* The name of the HTTP header. Example: "GET".
* Note: Header name is case sensitive.
* @param request
* The HTTP message.
* @return
* On success: The value following the HTTP header ": " (colon and whitespace).
* On failure: Empty string.
*/
public static String getHttpHeader(String header, String request) {
int startHeaderIndex = request.indexOf(header) + header.length();
int endHeaderIndex = request.indexOf('\n', startHeaderIndex);
/* Could not find the searched header. */
if (startHeaderIndex == -1 || endHeaderIndex == -1)
return "";
/* Add 2 to remove ':' and ' '(white space). Decrement 1 to exclude '\r' and '\n' */
return request.substring(startHeaderIndex + 2, endHeaderIndex - 1);
}
/**
*
* @param header
* The name of the HTTP header. Example: "Connection"
* Note: The header is case sensitive.
* @param value
* The new value you want to put. Example: "Close"
* @param request
* The HTTP message.
* @return
* On success: A new HTTP request with the modified header value.
* On failure: Empty string.
*
*/
public static String modifyHttpHeader(String header, String value, String request) {
int startHeaderIndex = request.indexOf(header) + header.length();
int endHeaderIndex = request.indexOf('\n', startHeaderIndex);
/* Could not find the searched header. */
if (startHeaderIndex == -1 || endHeaderIndex == -1)
return "";
String newRequest = "";
/* Copy all characters including ':' and ' ' (whitespace) */
for (int i = 0; i < startHeaderIndex + 2; i++) {
newRequest += request.charAt(i);
}
newRequest += value;
newRequest += "\r\n";
/* Add the rest of the request. */
for (int i = endHeaderIndex + 1; i < request.length(); i++) {
newRequest += request.charAt(i);
}
return newRequest;
}
}
public class Server {
public static void main(String[] args) throws Exception{
/* Receiving and parsing port number from command line arguments. */
int ssPort = 0;
if (args.length > 1 || args.length == 0){
System.err.println("Only one argument allowed; port number (int).");
System.exit(1);
} else {
try {
ssPort = Integer.parseInt(args[0]);
} catch(NumberFormatException exception) {
System.err.println("Argument \"" + args[0] + "\" must be a number.");
System.exit(1);
}
}
ServerSocket serverSocket = new ServerSocket(ssPort); /* Creating the server socket. */
System.out.println("Proxy running on port: " + ssPort);
while(true) {
System.out.println("Waiting for client...");
Socket clientSocket = serverSocket.accept(); /* Listening for connections. */
BufferedReader bReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String request = "";
int tmpData;
while ((tmpData = bReader.read()) != -1) {
request += (char)tmpData;
}
Client clientObject = new Client(request, clientSocket);
Thread clientThread = new Thread(clientObject);
clientThread.start(); /* Start the client thread. */
}
}
}
答案 0 :(得分:1)
扔掉它。这不是代理的编写方式。 HTTP代理应该:
你应该不尝试组装整个请求,甚至是标题,并且上面的“字节”和“同时”这两个词是至关重要的。请注意,您不必对HTTP保持活动,for(i in seq_along(data)){
Hmisc::label(data[, i]) <- var.labels[i]
}
label(data)
#> age sex
#> "Age in Years" "Sex of the participant"
标头,HTTPS等执行任何操作。