Server.java:
//导包
import java.net.*;
import java.io.*;
import java.util.*;
public class Server {//服务器端
//定义端口
static private int PORT =8000;
//回车换行
static private String CRLF = "\r\n";
//数组大小常量
static private int buffer_size = 99999;
//服务器资源路径
static File root;
/*
获取文件路径,考虑到了各种情况
*/
private static String getFileURI(String uri) {
if (uri.startsWith("http://")) {
return uri.substring(uri.indexOf('/',8)+1);
} else if (uri.startsWith("/")) {
return uri.substring(1);
}else if(uri.startsWith("www")){
return uri.substring(uri.indexOf('/',8)+1);
} else return uri;
}
//创建一个标准的http协议响应格式
private static String makeResponse(int num, String msg, String header) {
return "HTTP/1.0" + " " + num + " " + msg + CRLF + header + CRLF;
}
//创建MIME类型格式
private static String getMIME(String type, int len) {
String mm =
"Server: SimpleServer/1.0" + CRLF +
"Content-type: " + type + CRLF +
"Content-length: " + len + CRLF;
return mm;
}
//出错提示信息
private static String error(int code, String msg) {
//构造html页面
String html_page = "<HTML>" + "<BODY>" + CRLF +
"<H1>" + code + " " + msg + "</H1>" + "</BODY>" + "</HTML>" + CRLF;
//把MIME格式加到输出形式里
String mh = getMIME("text/html", html_page.length());
//把响应的号码加入到输出形式里
String hr = makeResponse(code, msg, mh);
//返回整个输出形式
return hr + html_page;
}
//根据文件名得到文件类型
private static String getType(String filename) {
//判断是否以html/htm结束的文件,并返回string类型
if (filename.endsWith(".html")||filename.endsWith(".htm")) {
return "text/html";
} else if (filename.endsWith(".jpg")||filename.endsWith(".jpeg")) {
//判断是否以jpg/jpeg结束的文件,并返回string类型
return "image/jpeg";
//默认text类型
} else return "text";
}
//处理从客户端得到的get指令信息
private static void handleGet(BufferedOutputStream outToClient, String uri) {
try {
String filename =getFileURI(uri);
File f = new File(root, filename);
if (!f.exists()) {
outToClient.write((error(404,"File not found")).getBytes());//文件不存在404错误
} else {
//存在时给出输出
String type = getType(f.getName());
String header = getMIME(type,(int) f.length());
String response = makeResponse(200,"OK",header);
outToClient.write(response.getBytes());
//建立一个输入流
FileInputStream fstream = new FileInputStream(f);
//创建一个byte数组,用来存放写入的类容
byte[] buffer = new byte[buffer_size];
//判断是否写完
while(fstream.read(buffer) != -1) {
outToClient.write(buffer);
}
}
} catch (IOException e) {
System.out.println(e);
}
}
//处理put指令
private static void handlePut( BufferedReader inFromClient,
BufferedOutputStream outToClient,
String uri, int len) {
try {
String filename = getFileURI(uri);
File f = new File(root, filename);
String reply;
if (f.exists()) {
if (!f.isFile()) {
outToClient.write((error(403,"Forbidden")).getBytes());
return;
} else {
reply = error(200, "OK");}
} else {
reply = error(201, "Created");
}
FileOutputStream fstream = new FileOutputStream(f);
fstream.write(inFromClient.toString().getBytes());
fstream.flush();
fstream.close();
outToClient.write(reply.getBytes());
} catch (IOException ioe) {
System.out.println(3);
}
}
//main函数
public static void main(String [] args) {
//创建一个服务器
ServerSocket serverSocket = null;
//字符数出流
BufferedOutputStream outToClient = null;
//字符输入流
BufferedReader inFromClient = null;
//判断输入的参数是否正确并给出提示
if (args.length != 1) {
System.err.println("Usage: Server </path/to/www/directory>");
return;
}
try {//根据参数,创建服务器资源地址
root = new File(args[0]);
if (!root.isDirectory()) {//判断资源文件是否存在,或者是否是一个文件夹.
System.err.println
(root.getAbsolutePath() + " does not exist or is not a directory");
return;
}
} catch ( Exception e ) {
System.out.println("Exception has occured!");
return;
}
//创建一个客户端实例
try {
serverSocket = new ServerSocket(PORT);
} catch (Exception e) {
System.out.println("Exception has occured!");
}
//服务器和客户端交互
while (true) {
try {//客户端与服务器连接
Socket socket = serverSocket.accept();
try {
//客户端输出流
outToClient = new BufferedOutputStream(socket.getOutputStream());
//服务器输入流
inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
serverSocket.close();
//关闭
boolean inHeader = true; // 循环控制
String header =new String();
String temp;
while (inHeader) {
temp = inFromClient.readLine(); //从客户端得到信息
if (temp == null)
break;
if (inHeader==true&& temp.length() == 0)
inHeader= false;
if (inHeader == true){
header = header + "\n" + temp;
}
}
StringTokenizer st = new StringTokenizer(header);//一个单词一个单词读
String method = st.nextToken();
String uri = st.nextToken();
//判断是否是get/GET
if (method.equals("GET")||method.equals("get")) {
{
handleGet(outToClient, uri);
}
} else if (method.equals("PUT")||method.equals("put")) {//PUT/put
int len = -1;
while(st.hasMoreTokens()) {
String line = st.nextToken();
if (line.startsWith("Content-Length:")) {
String length = line.substring(line.indexOf("/")+1);
len = length.length();
break;
}
}
if (len > 0) {
handlePut( inFromClient, outToClient, uri, len);
} else {
//400错误请求
outToClient.write((error(400, "Bad Request.")).getBytes());
serverSocket.close();
}
} else {
serverSocket.close();
outToClient.write((error(501, "Not Implemented")).getBytes());
}
} catch (NoSuchElementException e) {
System.out.println(e);
}
outToClient.flush();
socket.close();
outToClient.close();
} catch( Exception e ){
System.out.println("失去了和主机的连接。");//断开连接
break;
}
}
}
}
client.java:
//导入所需要的包
import java.net.*;
import java.io.*;
//客户端程序
public class Client
{
//客户端端口号
private static int PORT = 80;
//静态常量用于给数组规定大小
private static int buffer_size = 8192;
//回车换行
private static String CRLF = "\r\n";
//从键盘标准输入到缓存
static BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
//屏幕输出
static PrintWriter screen = new PrintWriter (System.out, true);
//主函数
public static void main( String [] args ) {
try{
//发给服务器的缓存
BufferedOutputStream outToServer = null;
//从服务器得到的
BufferedReader inFromServer = null;
//声明一个有一定大小的数组
byte[]buffer = new byte[buffer_size];
String header = new String();
String body = new String();
//判断是否正确输入参数
if (args.length != 1) {
System.err.println("Usage: Client <server>");
System.exit(0);
}
//建立一个客户实例
Socket socket = new Socket("localhost", 8000);
//向屏幕打印
screen.println(args[0] + " is listening to your request:");
//从服务器将客户端要的信息读入
inFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//把信息写到服务器
outToServer = new BufferedOutputStream(socket.getOutputStream());
//读入键盘输入的信息
String request = keyboard.readLine();
//确保是以回车换行结束
request += CRLF + CRLF;
//将键盘输入的信息传给byte数组
buffer = request.getBytes();
//在将此信息传个服务器
outToServer.write(buffer, 0, request.length());
//强制写入到服务器
outToServer.flush();
boolean inHeader = true;
String temp;
while (true) { //循环控制
temp = inFromServer.readLine(); //从服务器读出类容信息
if (temp == null) //判断是否读完
break;
if (inHeader==true && temp.length() == 0)
inHeader= false;
if (inHeader == true)
header = header + "\n" + temp;
else
body =body+ "\n" + temp;
}
//打印信息头
screen.println( "Header: \n" );
screen.print( header + "\n" );
screen.flush();
//保存信息到指定文件
screen.println();
screen.print("Enter the name of the file to save: \n");
screen.flush();
String filename = keyboard.readLine();
File f=new File("C:\\Documents and Settings\\Administrator\\桌面\\"+filename);
FileOutputStream outfile = new FileOutputStream(f);
outfile.write(body.getBytes());//往文件写入信息内容
screen.println(filename+"默认保存在了桌面上,请查看!");
outfile.flush();
outfile.close();
socket.close();
outToServer.close();
inFromServer.close();//关闭流
}catch(Exception e){//出现异常时,给出以下信息
screen.println(" 对不起,连接失败。请尝试以下解决方案:");
screen.println(" ************************************");
screen.println(" ** 1.查看服务器是否已打开 **");
screen.println(" ** 2.查看服务器是否支持多线程服务 **");
screen.println(" ** 3.结束已运行的服务,重启服务器 **");
screen.println(" ************************************");
}
}
}
ThreadedServer.java:
import java.net.*;
import java.io.*;
import java.util.*;
//实现多线程runnable接口
class Handle implements Runnable {
static private String CRLF = "\r\n";
static private int buffer_size = 8192;
static PrintWriter stdOut = new PrintWriter (System.out, true);
static File root;
Socket socket ;
public Handle(Socket s,File r){
//构造方法初始化属性
this.socket=s;
this.root=r;
Thread t=new Thread(this, "Server Thread");
t.start();
}
//得到请求的文件名
private static String getUriFile(String uri) {
if (uri.startsWith("http://")) {
return uri.substring(uri.indexOf('/',8)+1);
} else if (uri.startsWith("/")) {
return uri.substring(1);
}else if (uri.startsWith("/")){
return uri.substring(1);
} else return uri;
}
//创建一个标准的http协议响应格式
private static String makeResponse(int code, String msg, String header) {
return "HTTP/1.0" + " " + code + " " + msg + CRLF + header + CRLF;
}
//创建MIME类型格式
private static String getMIME(String type, int len) {
String mm =
"Server: SimpleServer/1.0" + CRLF +
"Content-type: " + type + CRLF +
"Content-length: " + len + CRLF;
return mm;
}
//出错提示信息
private static String error(int code, String msg) {
//构造html页面
String html_page = "<HTML>" + "<BODY>" + CRLF +
"<H1>" + code + " " + msg + "</H1>" + "</BODY>" + "</HTML>" + CRLF;
//把MIME格式加到输出形式里
String mh = getMIME("text/html", html_page.length());
//把响应的号码加入到输出形式里
String hr = makeResponse(code, msg, mh);
//返回整个输出形式
return hr + html_page;
}
//根据文件名得到文件类型
private static String getType(String filename) {
//判断是否以html/htm结束的文件,并返回string类型
if (filename.endsWith(".html")||filename.endsWith(".htm")) {
return "text/html";
} else if (filename.endsWith(".jpg")||filename.endsWith(".jpeg")) {
//判断是否以jpg/jpeg结束的文件,并返回string类型
return "image/jpeg";
//默认text类型
} else return "text/plain";
}
//处理从客户端得到的get指令信息
private static void handleGet(DataOutputStream ToClient, String uri) {
try {
//文件不存在404错误
String filename = getUriFile(uri);
File f = new File(root, filename);
if (!f.isFile()) {
ToClient.write((error(404,"File not found")).getBytes());
} else {
//存在时给出输出
String type = getType(f.getName());
String header = getMIME(type,(int) f.length());
String response = makeResponse(200,"OK",header);
ToClient.write(response.getBytes());
//建立一个输入流
FileInputStream fstream = new FileInputStream(f);
//创建一个byte数组,用来存放写入的类容
byte[] buffer = new byte[buffer_size];
//判断是否写完
while(fstream.read(buffer) != -1) {
ToClient.write(buffer);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
//处理put指令
private static void handlePut( BufferedReader inFromClient,
DataOutputStream outToClient,
String uri, int len) {
try {
String filename = getUriFile(uri);
File f = new File(root, filename);
String reply;
if (f.exists()) {
if (!f.isFile()) {
outToClient.write((error(403,"Forbidden")).getBytes());
return;
} else {
reply = error(200, "OK");}
} else {
reply = error(201, "Created");
}
FileOutputStream fstream = new FileOutputStream(f);
fstream.write(inFromClient.toString().getBytes());
fstream.flush();
fstream.close();
outToClient.write(reply.getBytes());
} catch (IOException ioe) {
ioe.printStackTrace();
} }
//覆写run()方法,实现多线程操作
public void run() {
try {
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
DataOutputStream ToClient =new DataOutputStream(socket.getOutputStream());
// 一直读写直到"\r\n\r\n";
// BufferedOutputStream outToClient = new BufferedOutputStream(socket.getOutputStream());
boolean inHeader = true; // 循环控制}
String header =new String();
String temp;
while (inHeader) {
temp = inFromClient.readLine();
if (temp == null)
break;
if (inHeader==true&& temp.length() == 0)
inHeader= false;
if (inHeader == true){
header = header + "\n" + temp;
}
}
StringTokenizer st = new StringTokenizer(header);//一个单词一个单词读
String method = st.nextToken();
String uri = st.nextToken();
//判断是否是get/GET
if (method.equals("GET")||method.equals("get")) {
{
handleGet(ToClient, uri);
}
//判断是否是PUT/put
} else if (method.equals("PUT")) {
//算出put 文件类容的长度
int len = -1;
while(st.hasMoreTokens()) {
String line = st.nextToken();
if (line.startsWith("Content-Length:")) {
String length = line.substring(line.indexOf(' ')+1);
len = new Integer(length).intValue();
break;
}
}
//大于0的话,继续put
if (len > 0) {
handlePut( inFromClient, ToClient, uri, len);
} else {
//如果出错给出错误提示
ToClient.write((error(400, "Bad Request.")).getBytes());
}
} else {
//如果不是get/put给出错误提示
ToClient.write((error(501, "Not Implemented")).getBytes());
}
socket.close();
} catch (NoSuchElementException nse) {
nse.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
}
}
public class ThreadedServer {
//main函数
static PrintWriter stdOut = new PrintWriter (System.out, true);
static private int PORT =8000;
public static void main(String [] args) {
File root;
ServerSocket serverSocket = null;
//输入参数是否正确
if (args.length != 1) {
System.err.println("Usage: Server </path/to/www/directory>");
return;
}
//判断资源文件是否存在,或者是否是一个文件夹
try {
root = new File(args[0]);
if (!root.isDirectory()) {
System.err.println
(root.getAbsolutePath() + " does not exist or is not a directory");
return;
}
} catch ( Exception e ) {
e.printStackTrace();
return;
}
//创建一个服务器端,监听8000端口等待连接
try {
serverSocket = new ServerSocket(PORT);
} catch (Exception e) {
e.printStackTrace();
}
//服务器一直等待用户的连接
while (true) {
try {
Socket consocket = serverSocket.accept();
new Handle(consocket, root);
} catch( Exception e ){
stdOut.println(e);
e.printStackTrace();
}
}
}
}
differences.txt:
Describe the Differences between HTTP/1.0 and HTTP/1.1 :
1. HTTP 1.0 use Non-Persistent Connections. It only supports one-to-one relationship of IP addresses and servers; a new connection have to been made every time the client make a new request,and the server do not make record of the information about the client.
HTTP 1.1 supports persistent connections.
2.HTTP/1.1 support the Host request-header, avoiding the case that a port in an ip only can have one web site in http/1.0.
3.in http/1.0 the client can not send a new request before the last request is recieved by the client. but the http/1.1 can do it and reduced the whole request time. HTTP/1.1 also have the function of client identify , caching, and state management. but HTTP/1.0 does not.
ssd8ex1
最新推荐文章于 2024-02-17 18:58:22 发布