http web服务器java_基于HTTP的Web服务器编程

一、   内容概述

1.实验目的

1)  掌握网络应用程序的开发方法;2)  掌握Client/ Server结构软件的设计与开发方法;3)  掌握Socket机制的工作原理。

2.实验前的准备

1)  阅读教材关于TCP/IP协议和Socket的相关内容;2)  阅读WinSock编程指南;3)  阅读本实验所附内容;4)  熟悉VC++、C#或Java开发语言。

3.实验内容

1)利用Java语言,基于TCP编写一个简单的Web Server,要求可以实现单用户简单页面浏览;2)修改上述Web Server,实现多用户同时连接(多线程)请求。

4.实验要求

1)  实现Web 服务器能发送文本文档和图片文件,Web 客户端能接收服务器响应发来的文本文件和图片文件,并能判断通信时发生的一些简单的错误。

2)  在实验报告中要说明实现Web Server的主要步骤、关键类和作用、记录实验过程和实验结果。

二、   设计要点及解决方案

本实验采用Java网络编程技术开发;在服务器端和客户端分别使用ServerSocket 和 Socket 来创建面向字节流、面向连接的TCP 套接字;在服务器端采用多线程来处理各个客户的连接。模拟HTTP请求·应答模型进行 Web 服务器与Web客户机间的通信。对文本文件与图片文件数据的传输分别字符输入输出流和字节输入输出流,以便于处理。(文本文档仅限于*.html和*.htm)

服务器程序的基本流程是:

1)  创建服务器端套接字并调用其accept( )等待接受客户端的连接请求。

2)  当与新的客户端连接之后,创建并启动一个新的线程来处理这个新的连接。主线程继续等待接受其他客户端的连接。

3)  与客户端进行通信为客户端提供服务。首先,接受客户端发来的HTTP请求消息;然后,判断该请求是否正确,若错误,则继续判断是请求消息的书写格式不正确还是服务器端找不到请求的文件错误,若正确,则继续判断请求的文件类型:文本文件或图片文件;最后,根据判断的结果向客户端发送HTTP应答消息。

4)  关闭输入输出流、关闭套接字,继续等待接受其他客户端的连接。

客户端程序的基本流程是:

1) 创建与服务器端连接的套接字。

2) 从标准输入接受用户输入的URL,向Web 服务器发送请求该URL代表的资源的请求消息。

3) 接受服务器发来的应答消息并进行处理。首先,根据应答消息状态行和首部判断应答消息的类型,若状态行的原因短语为“错误请求”或“文件找不到”,则置BadRequireFlag 为1,退出程序;否则,然后,根据"Content-Type:"判断应答主体的类型:字符流或字节流,根据判断结果启用相应的输入输出流读写数据。

4) 退出程序。

三、   源代码

1 /**

2 * @(#)HttpServer.java3 *4 * HttpServer application5 *6 *@author邝翼飞7 *@version1.00 2010/12/158 */

9

10 import java.io.*;11 import java.net.*;12 import java.util.*;13 import java.text.*;14

15 public classHttpServer16 {17

18 public static voidmain(String[] args)19 {20 String root="D:\\httpserver";21 int port=800;22 int count=20;23 ServerSocket SvrSock;24

25 try

26 {27 SvrSock=newServerSocket(port,count);28 System.out.println("Server has started. Begin listening...");29

30 while(true)31 {32 Socket Client=SvrSock.accept();33 InetAddress clientAddress=Client.getInetAddress();34 System.out.println("Client: "+clientAddress.toString()+ " has connected");35 serviceThread st=newserviceThread(Client,root);36 st.start();37 }38 }39 catch(IOException e)40 {41 System.out.println("Server Exception !");42 e.printStackTrace();43 }44 }45 }46

47 class serviceThread extendsThread48 {49 privateString root;50 privateFile file;51 private final String NEWLINE="\r\n";52 privateString requestfile;53 privateString FileType;54 privateSocket client;55 privateInetAddress cAddress;56 privateBufferedReader in;57 privatePrintStream out;58 privateDataOutputStream out2;59 private int errflag=-1;60

61 publicserviceThread(Socket s,String root)62 {63 client=s;64 cAddress=s.getInetAddress();65 this.root=root;66 FileType=".html";67 }68

69 public voidrun()70 {71 try

72 {73 in=new BufferedReader(newInputStreamReader(client.getInputStream()));74 out=new PrintStream(client.getOutputStream(),true);75

76 System.out.println("来自客户端的请求消息:");77 System.out.println("-----------------------------------");78 String type=in.readLine();79 System.out.println(type);80 String sss=new String("");81 char ch[]={1,2,3,4,5};82 while(true)83 {84 sss=in.readLine();85 if(sss.equals(String.valueOf(ch)))86 break;87 System.out.println(sss);88 }89 System.out.println("-----------------------------------");90

91 int testtype=testType(type);92 if(testtype==-1)93 {94 if(errflag==0)95 {96 System.out.println("客户端请求格式错误");97 sendHead(400,FileType,0);98 }99 else

100 {101 System.out.println("文件未找到");102 sendHead(404,FileType,0);103 }104 }105 else

106 {107 try

108 {109 FileInputStream fins=newFileInputStream(requestfile);110 long filesize=fins.available();111 switch(testtype)112 {113 case 0:114 BufferedReader fin=new BufferedReader(newFileReader(requestfile));115 if(fins!=null)116 {117 sendHead(200,FileType,filesize);118

119 String ss=fin.readLine();120 while(ss!=null)121 {122 out.println(ss);123 ss=fin.readLine();124 }125 //out.println(NEWLINE);

126 out.println(String.valueOf(ch));127 out.flush();128 fins.close();129 fin.close();130 }131 break;132 case 1:133 DataInputStream fin2=new DataInputStream(newBufferedInputStream(fins));134 out2=new DataOutputStream(newBufferedOutputStream(client.getOutputStream()));135

136 if(fins!=null)137 {138 sendHead(200,FileType,filesize);139

140 int count=0;141 inti;142 while((i=fin2.read())!=-1)143 {144 out2.write(i);145 count++;146 }147 out2.flush();148 fins.close();149 out2.close();150 System.out.println("Bytes number: "+count);151 }152 break;153 default: break;154 }155 }156 catch(FileNotFoundException e)157 {158 System.out.println("文件未找到");159 sendHead(404,FileType,0);160 }161 }162

163 System.out.println("数据响应已完成\n");164 client.close();165 }166 catch(IOException e)167 {168 System.out.println("run() service exception !");169 e.printStackTrace();170 }171 }172

173 public inttestType(String filetype)174 {175 int type=-1;176

177 filetype=filetype.substring(3,filetype.length()-8).trim(); //获取请求的Url

178 if((!filetype.startsWith("/")) && (!filetype.startsWith("\\")))179 {180 errflag=0;181 returntype;182 }183 requestfile=root+filetype;184 requestfile=requestfile.replace('/','\\');185 if(filetype.indexOf('.')!=-1)186 {187 FileType=filetype.substring(filetype.lastIndexOf('.'));188 boolean istxt=FileType.endsWith(".html") || FileType.endsWith(".htm");189 boolean ispic=FileType.endsWith(".gif") || FileType.endsWith(".jpg") || FileType.endsWith(".bmp") || FileType.endsWith(".jpeg");190 if(istxt)191 type=0;192 else if(ispic)193 type=1;194 }195 else

196 errflag=0;197 returntype;198 }199

200 public void sendHead(int code,String type,longsize)201 {202 String message;203 String state="OK";204 message="HTTP/1.1 ";205

206 switch(code)207 {208 case 200:209 state=" 请求成功"; break;210 case 400:211 state=" 错误请求"; break;212 case 404:213 state=" 文件找不到"; break;214 default:215 state=" OK"; break;216 }217 message += String.valueOf(code) + state +NEWLINE;218

219 SimpleDateFormat df=new SimpleDateFormat("E yyyy-MM-dd HH:mm:ss");220 message +="Date: " +df.format(new Date()) +NEWLINE;221

222 if(FileType.equals(".jpg") || FileType.equals(".gif") || FileType.equals(".jpeg") || FileType.equals(".bmp"))223 message += "Content-Type: image/"+FileType.substring(1)+NEWLINE;224 else

225 message += "Content-Type: text/"+FileType.substring(1)+NEWLINE;226

227 message += "Content-Length: "+String.valueOf(size)+NEWLINE+NEWLINE;228 out.print(message);229 out.flush();230 }231 }

1 /**

2 * @(#)HttpClient.java3 *4 * HttpClient application5 *6 *@author邝翼飞7 *@version1.00 2010/12/158 */

9

10 import java.io.*;11 import java.net.*;12 import java.util.*;13

14

15 public classHttpClient16 {17 privateString root;18 privateBufferedReader in;19 privateBufferedWriter out;20 privateDataInputStream in2;21 privateDataOutputStream out2;22 privatePrintStream txtFile;23 privateBoolean head;24

25 public static voidmain(String[] args)26 {27 HttpClient httpclient;28 if(args.length==1)29 httpclient=new HttpClient(args[0],800,"D:\\httpclient");30 else

31 httpclient=new HttpClient("localhost",800,"D:\\httpclient");32 System.out.print("请输入URL:");33 String urlstr=newScanner(System.in).nextLine();34 httpclient.send(urlstr);35 System.out.println("来自服务器的应答");36 System.out.println("-----------------------------------");37 httpclient.response();38 }39

40 public HttpClient(String address,intport,String root)41 {42 try

43 {44 this.root=root;45 head=true;46 Socket socket=newSocket(address,port);47 in=new BufferedReader(newInputStreamReader(socket.getInputStream()));48 out=new BufferedWriter(newOutputStreamWriter(socket.getOutputStream()));49 in2=new DataInputStream(newBufferedInputStream(socket.getInputStream()));50 System.out.println("与服务器的连接已建立.");51 }52 catch(IOException e)53 {54 System.out.println("Create socket to server failed !");55 e.printStackTrace();56 System.exit(1);57 }58 }59

60 public voidsend(String Url)61 {62 String ss=null;63 try

64 {65 if(Url.equals("/") || Url.equals("/index.html") || Url.equals("www.kuangyifei.com")66 || Url.equals("http://www.kuangyifei.com"))67 ss="GET /index.html HTTP/1.1\r\n";68 else if(Url.startsWith("www.kuangyifei.com/") || Url.startsWith("http://www.kuangyifei.com/"))69 ss="GET " + Url.substring(Url.indexOf('/')) + " HTTP/1.1\r\n";70 else

71 ss="GET " + Url + " HTTP/1.1\r\n";72

73 ss+="Accept: text/html\r\n";74 ss+="Accept: image/gif, image/x-xbitmap, image/jpg, image/jpeg\r\n";75 ss+="Host: www.kuangyifei.com\r\n";76 ss+="Connection: Keep-Alive\r\n";77 out.write(ss);78 char ch[]={1,2,3,4,5};79 out.write(String.valueOf(ch)+"\r\n");80 out.flush();81 }82 catch(IOException e)83 {84 System.out.println("Send Exception !");85 e.printStackTrace();86 }87 }88

89 public voidresponse()90 {91 String line,ss;92 StringTokenizer st;93 String type="text";94 inti;95

96 try

97 {98 File TxtFile;99 File PicFile;100 BufferedWriter outfile;101 int contentlength=0;102 int BadRequireFlag=0;103 while((line=in.readLine())!=null)104 {105 if(line.equals(""))106 if(head)107 head=false;108 if(head)109 {110 System.out.println(line);111 st=newStringTokenizer(line);112 ss=st.nextToken();113 if(ss.equals("HTTP/1.1"))114 {115 ss=st.nextToken();ss=st.nextToken();116 if(ss.equals("错误请求") || ss.equals("文件找不到"))117 BadRequireFlag=1;118 }119 if(ss.equals("Content-Type:"))120 {121 ss=st.nextToken();122 i=ss.indexOf('/');123 String substr=ss.substring(0,i);124 if(substr.equals("text"))125 type="text";126 else

127 {128 type="pic";129 String substr2=ss.substring(i+1);130 PicFile=new File(root,"PicFile."+substr2) ;131 out2=new DataOutputStream(newFileOutputStream(PicFile));132 }133 }134 if(ss.equals("Content-Length:"))135 {136 ss=st.nextToken();137 contentlength=Integer.parseInt(ss);138 }139

140 }141 else if(BadRequireFlag==1)142 {143 System.out.println("-----------------------------------");144 System.exit(1);145 }146 else

147 {148 if(type.equals("text"))149 {150 TxtFile=new File("D:\\httpclient","TxtFile.html") ;151 outfile=new BufferedWriter(newFileWriter(TxtFile));152 int count=0;

154 char ch[]={1,2,3,4,5};

156 while(line!=null)157 {158 System.out.println(line);159 outfile.append(line+"\r\n");160 outfile.flush();161 line=in.readLine();162 if(line.equals(String.valueOf(ch)))163 break;164 }165 System.out.println("-----------------------------------");166 System.out.println("数据已成功传输完毕");167 outfile.close();in.close();168 break;169 }170 else if(type.equals("pic"))171 {172 int ch=in2.read();173 while(ch!=-1)174 {175 out2.write(ch);176 ch=in2.read();177 }178 out2.flush();179 in2.close();180 out2.close();181 System.out.println("-----------------------------------");182 System.out.println("数据已成功传输完毕");183 break;184 }185

186 }187 }188 }189 catch(IOException e)190 {191 System.out.println("Response exception !");192 e.printStackTrace();193 }194 }195 }

四、   运行截图

说明:运行的过程是:开启服务器端, 开启四个客户端,四个客户端分别向服务器端发送请求,请求的格式分别是:根文件夹中存在的文本文件、根文件夹中存在的图片文件、不正确的格式、根文件夹中 不存在的文件。另外由于电脑不够,只能在本机测试,所以所有的客户端的IP地址均为:127.0.0.1。

服务器端运行截图:

973a806320f1443a5a4fd9d0956a20df.png

客户端运行截图:

客户端1:IP地址 127.0.0.1

25107d2c15ec5b3fbcdf177e0364c7f3.png

客户端2:IP地址 127.0.0.1

2aacec9dbbca3cf6a08e559bf0004b92.png

客户端3:IP地址 127.0.0.1

9f8cf6486aae8e42ce51399e00f2a281.png

客户端4:IP地址 127.0.0.1

3075a4ce0d6b6a7d98dfb9bef51b92d2.png

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
评论

打赏作者

拉菲雪球兔

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值