Exam 1 of SSD 8 -- JAVA
——满分作业~哈哈哈哈!8易啊~~~
[题目要求]实现网络代理服务器的功能。
[关键技术]其实就是一个Client和一个Server的结合,做过Exercise 1的同学应该对此并不感到陌生吧!但其中的很多细节部分是值得我们留意的,稍有不小心就会导致代理失败。
[心得体会]要注意字符串处理的一道道门槛的实现是否合理;另外输入输出流的问题也非常容易使自己的努力无法得到收效;最后,多线程中套接字和输入输出流的"善后处理"的问题——已经是老生常谈了。
稍候详细介绍……
本着学术交流的目的和宗旨,欢迎大家的七嘴八舌~
iCarnegie-SSD8-Exam1原题如下:
[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
本人编写的程序ReadMe文件如下:
引用:
Readme for Exam 1 of SSD 8
Here are the instructions on compiling and running each program:
ProxyServer.java
First, compile this java file through cmd:
javac ProxyServer.java
to ProxyServer.class. Second, run this class file also through cmd:
java ProxyServer
Then you can see the guide for input the request if the connection is OK. Now, input the request. For example:
GET http://www.icarnegie.com/index.html HTTP/1.0
Or
GET http://www.icarnegie.com:80/index.html HTTP/1.0
Then the web file will be received.
You can also get web files through the web browser. Take IE for example, input
http://www.icarnegie.com/index.html
Or
http://www.icarnegie.com:80/index.html
into the URL text and press ENTER. Then you can get the web in the screen.
本人编写的代理服务器程序代码如下:
FileName: WebProxyServer.java
import java.io.*;
import java.net.*;
import java.util.StringTokenizer;
/**
* A Web proxy server which is both a client and a server at the same time.
*
* @author Zhao Jinjiang
*/
public class WebProxyServer {
public WebProxyServer() throws Exception {
/* the server socket */
ServerSocket serSk = new ServerSocket(8080);
/* the counter of clients */
int counter = 1;
while (true) {
Socket cliSk = serSk.accept();
System.out.println("Accepting Client " + counter
+ "'s Connection...\n");
/* a thread for a client */
ServerThread st = new ServerThread(cliSk, counter++);
st.start();
}
}
class ServerThread extends Thread {
/* a client socket */
private Socket sk;
/* the counter of clients */
private int counter;
ServerThread(Socket sk, int counter) {
this.sk = sk;
this.counter = counter;
}
public void run() {
/* reader and writer */
BufferedReader inFromClient = null;
DataInputStream inFromServer = null;
DataOutputStream outToClient = null;
DataOutputStream outToServer = null;
/* response the request */
try {
while (true) {
/* Reader and writer between proxy server and client */
inFromClient = new BufferedReader(new InputStreamReader(sk
.getInputStream()));
outToClient = new DataOutputStream(sk.getOutputStream());
System.out.println("Waiting for Client " + counter
+ "\'s command...");
String cmd = inFromClient.readLine();
System.out.println("The Client " + counter
+ " request for: " + cmd);
/*
* Process the command from client and identify the method
* and address. If command error, write the error response
* and break.
*
*/
StringTokenizer token = new StringTokenizer(cmd);
if (token.countTokens() < 2) {
System.out.println("Command style error!");
outToClient.writeBytes("HTTP/1.1 400 Bad Request\n\r");
break;
} else {
String method = token.nextToken();
String url = token.nextToken();
if (!method.equals("GET")) {
System.out.println("method error!");
System.out.println("HTTP/1.1 400 Bad Request\n\r");
break;
}
if (!url.toUpperCase().startsWith("HTTP://")) {
System.out.println("url error!");
System.out.println("HTTP/1.1 400 Bad Request\n\r");
break;
}
/*
* process the file name and make sure the server name,
* the file path and the number of port.
*/
int port = 0;
int strIndex = 0;
String serverName = "";
String portToString = "";
String filePath = "";
url = url.substring(7);
strIndex = url.indexOf("/");
serverName = url.substring(0, url.indexOf("/"));
filePath = url.substring(url.indexOf("/"));
if (serverName.contains(":")) {
strIndex = serverName.indexOf(":");
portToString = serverName.substring(strIndex + 1);
serverName = serverName.substring(0, strIndex);
} else {
portToString = "80";
}
port = Integer.parseInt(portToString);
/*
* Response the right format request. Identify the file
* tpye and write it to the client.
*
*/
System.out.println(serverName);
System.out.println(port);
System.out.println(filePath);
System.out.println(url);
System.out.println("Now respond the Client " + counter
+ "\'s request...");
/* the client socket */
Socket clientSocket = new Socket(serverName, port);
/* Reader and writer between proxy server and server */
inFromServer = new DataInputStream(clientSocket
.getInputStream());
outToServer = new DataOutputStream(clientSocket
.getOutputStream());
outToServer.writeBytes("GET " + filePath
+ " HTTP/1.0\r\n\r\n");
/* read from server and write to client */
String response = inFromServer.readLine();
while (!response.equals("")) {
response = inFromServer.readLine();
}
byte[] bytes = new byte[1024];
int size = 0;
while ((size = inFromServer.read(bytes, 0, 1024)) != -1) {
outToClient.write(bytes, 0, size);
}
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
/*
* Close the reader, writer and client socket.
*
*/
System.out.println("Closing Client " + counter
+ "\'s Connection...\n");
try {
if (inFromClient != null)
inFromClient.close();
if (outToClient != null)
outToClient.close();
if (inFromServer != null)
inFromServer.close();
if (outToServer != null)
outToServer.close();
if (sk != null)
sk.close();
} catch (IOException e) {
}
}
}
}
public static void main(String[] args) {
try {
WebProxyServer pServer = new WebProxyServer();
} catch (Exception e) {
e.printStackTrace();
}
}
}