您的当前位置:首页正文

ssd8 Exercise1

2023-06-28 来源:榕意旅游网


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 = \"\" + \"\" + CRLF +

\"

\" + code + \" \" + msg + \"

\" + \"\" + \"\" + CRLF;

//把MIME格式加到输出形式里

String mh = getMIME(\"text/html\

//把响应的号码加入到输出形式里

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\

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 \");

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 \");

System.exit(0);

}

//建立一个客户实例

Socket socket = new Socket(\"localhost\

//向屏幕打印

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 = \"\" + \"\" + CRLF +

\"

\" + code + \" \" + msg + \"

\" + \"\" + \"\" + CRLF;

//把MIME格式加到输出形式里

String mh = getMIME(\"text/html\

//把响应的号码加入到输出形式里

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\

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 InputStreamReader(socket.getInputStream()));

DataOutputStream ToClient DataOutputStream(socket.getOutputStream());

// 一直读写直到\"\\r\\n\\r\\n\";

// BufferedOutputStream outToClient BufferedOutputStream(socket.getOutputStream());

boolean inHeader = true; // 循环控制}

String header =new String();

String temp;

while (inHeader) {

temp = inFromClient.readLine();

BufferedReader(new

=new

= new

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 \");

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.

因篇幅问题不能全部显示,请点此查看更多更全内容