课程设计简单web服务器的设计与实现uml设计.docx
《课程设计简单web服务器的设计与实现uml设计.docx》由会员分享,可在线阅读,更多相关《课程设计简单web服务器的设计与实现uml设计.docx(17页珍藏版)》请在冰豆网上搜索。
课程设计简单web服务器的设计与实现uml设计
简单web服务器的设计与实现
一、设计内容及设计要求
WWW的工作基于客户机/服务器计算模型,由Web浏览器(客户机)和Web服务器(服务器)构成,两者之间采用超文本传送协议(HTTP)进行通信,HTTP协议的作用原理包括四个步骤:
连接,请求,应答,关闭应答。
设计内容
Web服务器是web中的关键部件,设计一个简单的Web服务器,为用户提供简单的信息服务。
设计要求
本实验要求完成一个简单的web服务器的设计与实现,能够通过HTTPGet命令获得一个简单的HTML文件。
设计目的
通过web服务器的设计与实现,可以达到以下目的:
掌握网络编程的知识与技能;掌握HTTP协议的相关知识;熟悉网络软件的开发过程,锻炼解决实际问题的能力。
二、总体设计
HTTP协议的作用原理包括四个步骤:
连接:
Web浏览器与Web服务器建立连接,打开一个称为socket(套接字)的虚拟文件,此文件的建立标志着连接建立成功。
请求:
Web浏览器通过socket向Web服务器提交请求。
HTTP的请求一般是GET或POST命令(POST用于FORM参数的传递)。
GET命令的格式为:
GET路径/文件名HTTP/1.0文件名指出所访问的文件,HTTP/1.0指出Web浏览器使用的HTTP版本。
应答:
Web浏览器提交请求后,通过HTTP协议传送给Web服务器。
Web服务器接到后,进行事务处理,处理结果又通过HTTP传回给Web浏览器,从而在Web浏览器上显示出所请求的页面。
关闭连接:
当应答结束后,Web浏览器与Web服务器必须断开,以保证其它Web浏览器能够与Web服务器建立连接。
客户端采用的是浏览器,整个系统需要设计的是服务器
服务器的用例描述
服务器实现的功能可以描述为3个用例
允许建立连接
提供服务
允许断开连接
服务器的活动图
整个工作流程如下
三、详细设计及代码
服务器对象的静态关系
服务器对象的静态关系
服务器类的设计
publicclassMain启动程序
publicclassFrameextendsJFrameimplementsActionListener实现系统管理员查看服务器状态
publicclassNet实现允许建立连接,提供服务,允许断开连接
代码
publicclassMain启动程序
packageserver;
//http:
//ylx-PC:
1111/index.html
publicclassMain{//接口的实现
publicstaticvoidmain(String[]args){//启动程序
newFrame();//建立窗体
}
}
publicclassFrameextendsJFrameimplementsActionListener实现系统管理员查看服务器状态
packageserver;
importjava.awt.*;
importjava.awt.event.*;
importjava.util.Date;
importjavax.swing.*;
publicclassFrameextendsJFrameimplementsActionListener{
//建立窗体组件
JPanelbtnPan=newJPanel(newFlowLayout(FlowLayout.CENTER));
privateJLabellistenPortLb=newJLabel("设置监听端口:
");
privateJLabeltishi=newJLabel("Webserver信息:
");
privateJLabeltian=newJLabel("");
privateJTextFieldportTf=newJTextField("8080",4);//设置默认端口号
JButtoncontrolBtn=newJButton("开始");//设置按钮名称
JButtonclearHintBtn=newJButton("清空");
privateJTextAreahintTa=newJTextArea("动态监测服务信息\n");
privateNetnet;
publicFrame(){
initComponent();//初始化界面
net=newNet(this);
}
privatevoidinitComponent(){//初始化所有界面组件
buildBtnPan();
buildHintPan();
setSize(600,450);//设置窗体大小
Toolkittool=Toolkit.getDefaultToolkit();
setLocation((tool.getScreenSize().width-this.getSize().width)/2,
(tool.getScreenSize().height-this.getSize().height)/2
);//设置窗体位置
this.addWindowListener(newWindowAdapter(){
publicvoidwindowClosing(WindowEventarg0){
Frame.this.setVisible(true);
Frame.this.dispose();
}
});
setTitle("一个简单的Web服务器");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
//构建按钮面板
publicvoidbuildBtnPan(){//实现窗体布局
JLabeltc=newJLabel();
BoxboxV1=Box.createHorizontalBox();
BoxboxV2=Box.createHorizontalBox();
Boxbox=Box.createVerticalBox();
boxV1.add(listenPortLb);
boxV1.add(Box.createHorizontalStrut(10));
boxV1.add(portTf);
boxV1.add(Box.createHorizontalStrut(10));
boxV1.add(controlBtn);
boxV2.add(tishi);
boxV2.add(Box.createHorizontalStrut(10));
boxV2.add(tian);
boxV2.add(Box.createHorizontalStrut(10));
boxV2.add(clearHintBtn);
box.add(boxV1);
box.add(Box.createVerticalStrut(8));
box.add(boxV2);
btnPan.add(box);//加入所有按键
add(btnPan,BorderLayout.NORTH);//将按键放置在北部面板
portTf.requestFocus();
portTf.selectAll();
controlBtn.addActionListener(this);
clearHintBtn.addActionListener(this);
}
publicvoidbuildHintPan(){
hintTa.setEditable(false);
JScrollPanescrollPane=newJScrollPane();//添加滑动条
scrollPane.setBorder(BorderFactory.createLoweredBevelBorder());
scrollPane.getViewport().add(hintTa);
add(scrollPane,BorderLayout.CENTER);//置在中部面板
}
publicvoidactionPerformed(ActionEventarg0){//各个出现的问题监测
Objectsource=arg0.getSource();
//判断按钮提示文字内容
if(source==clearHintBtn){
hintTa.setText("");
return;
}
Stringmsg=controlBtn.getText();
if(msg.equals("开始")){
controlBtn.setText("停止");
tian.setText("服务器启动接口"+portTf.getText());
portTf.setEditable(false);
net.start(portTf.getText());
hintTa.setText(hintTa.getText()+"\n---------------------------"+
"-开启服务器"+newDate().toLocaleString()+"---------------------------------\n\n");
}else{
tian.setText("关闭服务器接口"+portTf.getText());
controlBtn.setText("开始");
portTf.setEditable(true);
net.stop();
}
}
publicvoidaddHint(Strings){
hintTa.setText(hintTa.getText()+s);
}
}
publicclassNet实现允许建立连接,提供服务,允许断开连接
packageserver;
importjava.io.*;
import.*;
importjava.util.*;
importjavax.swing.*;
publicclassNet{//实现允许建立连接,提供服务,允许断开连接
inti=0;
privateFrameframe;
privateServerSocketserverSocket;
publicNet(Frameframe){//将WebServerFrame和WebServerNet连接起来
this.frame=frame;
}
//点击“开始”按钮出现的结果
publicvoidstart(Stringport){
//对异常进行处理
try{
serverSocket=newServerSocket(Integer.parseInt(port));
newThread(){
//对于线程重写run()
publicvoidrun(){
try{
while(true){
Socketsocket=serverSocket.accept();//允许与服务器连接
newHandlerThread(socket).start();//开启线程
}
}catch(Exceptione){
JOptionPane.showMessageDialog(frame,e.getMessage());
}
}
}.start();
}catch(Exceptionex){
JOptionPane.showMessageDialog(frame,ex.getMessage());
}
}
publicvoidstop(){
try{
if(serverSocket!
=null)
serverSocket.close();
}catch(Exceptione){
}finally{
frame.addHint("\n---------------------------"+
"-关闭服务器"+newDate().toLocaleString()+"--------------------------------\n");
}
}
//增加新的线程
classHandlerThreadextendsThread{
privateSocketsocket;
privateStringhostName;
publicHandlerThread(Socketsocket){
this.socket=socket;
this.hostName=socket.getInetAddress().getHostAddress();
i++;
frame.addHint(""+i+""+"主机"+hostName+"连接成功");
}
//重写run()
publicvoidrun(){
BufferedReaderin=null;//浏览器和服务器间交互的输入流
PrintStreamout=null;//浏览器和服务器间交互的输出流
BufferedInputStreamfin=null;//服务器端文件的输入字符流
try{
in=newBufferedReader(newInputStreamReader(socket.getInputStream()));
out=newPrintStream(socket.getOutputStream());
//从浏览器提交的请求头部中获得想访问的文件名称
Stringsrc=in.readLine().split("")[1];
//将浏览器想获得的文件名称输出至提示框
frame.addHint("获得服务"+"时间"+newDate().toLocaleString()+"\n");
//对浏览器想获得的文件名称进行去除?
后面内容处理
//示例:
/index.html?
a=b->/index.html
intindex=src.indexOf("?
");
if(index>=0)src.substring(0,index);
//如果浏览器没指定访问的页面,则返回index.html页面内容
if("/".equals(src))src="/index.html";
FilesrcFile=newFile("html"+src);
//如果浏览器访问的页面不存在,则返回404.html页面内容
if(!
srcFile.exists()||!
srcFile.canRead())
srcFile=newFile("html/404.html");
//输出响应头部信息
out.println("HTTP/1.1200OK");
out.println("服务器:
IISWeb服务器V01");
out.println("最后修改时间:
"+newDate(srcFile.lastModified()));
out.println("文件总字节:
"+getContentType(srcFile));
out.println("文件总长度:
"+srcFile.length());
out.println("时间:
"+newDate());
out.println();
//输出响应体部信息
fin=newBufferedInputStream(newFileInputStream(srcFile));
byte[]buffer=newbyte[1024*8];
inti=-1;
while((i=fin.read(buffer))!
=-1){
out.write(buffer,0,i);
}
}catch(Exceptione){
e.printStackTrace();
}finally{
try{
if(in!
=null)in.close();
if(out!
=null)out.close();
if(fin!
=null)fin.close();
}
catch(Exceptione){}
}
}
}
//文件的接收
publicStringgetContentType(Filefile){
StringfileName=file.getName();
Stringtype=fileName.substring(fileName.indexOf("."));
Stringresult="空";
if(".gif".equals(type))result="image/gif";
elseif(".html".equals(type))result="text/html";
elseif(".htm".equals(type))result="text/html";
elseif(".txt".equals(type))result="text/plain";
elseif(".xml".equals(type))result="text/xml";
returnresult;
}
}
四、调试及运行结果
启动用exe4j生成的myserver.exe应用程序
初始化如图
设置端口8080,单击开始开启服务器
打开浏览器地址栏输入http:
//ylx-pc:
8080/得到结果如图
服务器端结果
单击停止,暂停服务器服务
五、总结
通过此次实验,我基本了解了Web服务器的设计和工作原理,掌握了一些JAVA网络编程方法,更加深了我对书本知识的理解:
Web服务器与客户端的通信使用HTTP协议(超文本传输协议),所以也叫做HTTP服务器。
用Java构造Web服务器主要用二个类,.Socket和.ServerSocket,来实现HTTP通信。
课程设计在此基础上实现一个简单但完整的Web服务器。
HTTP协议是一种请求-应答式的协议——客户端发送一个请求,服务器返回该请求的应答。
HTTP请求由三个部分构成,分别是:
方法-URI-协议/版本,请求头,请求正文。
HTTP应答也由三个部分构成,分别是:
协议-状态代码-描述,应答头,应答正文。
Socket代表着网络连接的一个端点,应用程序通过该端点向网络发送或从网络读取数据。
位于两台不同机器上的应用软件通过网络连接发送和接收字节流,从而实现通信。
要把消息发送给另一个应用,首先要知道对方的IP地址以及其通信端点的端口号。
Socket类代表的是“客户”通信端点,它是一个连接远程服务器应用时临时创建的端点。
ServerSocket等待来自客户端的连接请求;一旦接收到请求,ServerSocket创建一个Socket实例来处理与该客户端的通信。
课程设计的过程中,我了解到课程设计不仅仅是编代码,更是做系统设计,同时也是和同学互相交流经验的过程。
课程设计是一个将书本知识转化为实际应用的难得机会,也是加强我们动手设计能力的机会。
设计难免会遇到了一些问题,但通过和同学交流,上网查资料,最终还是把问题解决了。
总的看来,我觉得这次课程设计使我的专业知识丰富了不少,但是同时也发现了自己在在专业方面存在的一些不足,例如知识不够系统,编程语言不能灵活的运用。
同时,这次课程设计也为我以后的学习指明了方向。