【发布时间】:2017-03-30 16:37:52
【问题描述】:
我在 Java 中创建了一个代理服务器,(见下面的代码),问题是,我从网络服务器得到响应,但是我的代理客户端处理客户端(浏览器)之间的连接以及使用代理的服务器端创建套接字后的网络服务器。服务器端创建一个客户端并发送请求和套接字,然后在一个新线程中处理。 我有几个问题:
第一个代码是代理的客户端第二个代码部分是代理的服务器端
- 在浏览器/代理/网络服务器之间发送数据时应该使用什么类型的流?
在从流中发送和接收时可以使用字符串还是应该使用某种类型的字节数组?
为什么浏览器没有从代理接收到任何东西?因为我可以从控制台打印出来,但是当写入流时,浏览器没有任何反应。
-
另外,为什么我需要在浏览器中点击两次“enter”才能让代理做出反应?
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. */ } }}
【问题讨论】:
标签: java multithreading sockets proxy stream