程序实践四实践报告.doc_第1页
程序实践四实践报告.doc_第2页
程序实践四实践报告.doc_第3页
程序实践四实践报告.doc_第4页
程序实践四实践报告.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

程 序 实 践 四实验报告姓 名谭竹青学 号20073387班 级软件0704指 导 教 师宋航程序实践名称程序实践(网络应用程序设计)程序实践内容计算机强化训练开 设 学 期2009-2010第一学期开 设 时 间第13周第15周报告日期2009年12月评 定 成 绩评定人签字评 定 日 期东北大学软件学院2程序实践四 1. 实践目的l 写出本次实践的目的,要求简洁清楚。(1) 通过查看 HTTP 协议的 RFC 文档,理解并掌握 HTTP 协议,加深理解 Web 的工作原理;(2) 掌握网络应用程序的开发方法;(3) 掌握 Socket 机制的工作原理(4) 能够用 Java 语言编写简单的 HTTP 1.0 客户端和服务器端的程序;(5) 理解并掌握 HTTP 协议,线程和进程的区别,加深理解 Web 的工作原理;(6) 掌握网络应用程序的开发方法;(7) 掌握 Socket 机制的工作原理(8) 能够用 Java 语言多线程机制,编写多线程服务器端的程序;(9) 理解并掌握分布式系统的基本概念;(10) 掌握分布式系统应用程序的开发方法;(11) 掌握 RMI 工作原理;(12) 能够用 Java 语言 RMI 机制,编写 RMI 程序;2. 预习内容 l 写出本次实践过程中你所用到的知识;(1) 复习 TCP/IP 协议栈;(2) 复习并掌握 Web 技术相关知识和 HTTP 协议;(3) 复习 Java 的网络编程相关知识;(4) 复习网络应用程序的开发方法;(5) 复习 Socket 机制;(6) 复习 Java 多线程编程相关知识;(7) 复习 Java 网络编程相关知识;(8) 复习 RMI 机制;3. 实践内容和实践过程1. 编写简单的HTTP 1.0 客户端程序,编写简单的HTTP 1.0 服务器程序;(1) 实践内容a. 对比 HTTP1.0 与 HTTP1.1 的差异HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器完成请求处理后立即断开TCP连接,服务器不跟踪每个客户也不记录过去的请求.HTTP 1.1支持持久连接,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍然需要使用各自的连接。HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样也显著地减少了整个下载过程所需要的时间。基于HTTP 1.1协议的客户机与服务器的信息交换过程。b. 编写简单的 HTTP 1.0客户端程序c. 编写简单的 HTTP 1.0服务器程序(2) 实现过程Socket和端口、IP地址的关系:实现socket编程的具体流程:开始Socket生成连接接受请求接通关闭开始接通关闭Socket生成ConnectReadWrite Server 端socket client 端socketl 注意: 具体体现Socket的编程流程,注意区分Java Socket与其它Socket的区别; 在此实践中某些功能模块的实现流程; 最好利用UML的类图或结构化的程序流程图来描述程序的实现过程;(3) 关键技术l 关键写出在完成各个功能时所使用的具体函数,但不要将全部程序代码粘贴;Server端主要代码:Socket生成:final static int port = 8000;ServerSocket welcomeSocket = new ServerSocket(port); Socket接受连接请求: Socket httpSocket = welcomeSocket.accept(); 接通时System.out.println(已经与+port+端口建立连接.); Read和write流:BufferedReader inFromClient = new BufferedReader(new InputStreamReader(httpSocket.getInputStream() );OutputStream os = httpSocket.getOutputStream(); 处理请求,在GET后获取请求的文件名,如果该文件存在,服务端打开该文件并发送正确的响应报头,不存在则发送提示错误的信息及相应的响应报头:System.out.println(客户端的请求:+clientSentence);StringTokenizer s = new StringTokenizer(clientSentence); String temp = s.nextToken(); String fName = null; if(temp.equals(GET) String fileName = s.nextToken(); fName = fileName.substring(0); fileName = . + fileName; FileInputStream fis = null; boolean fileExists = true; try fis = new FileInputStream(fileName); catch(FileNotFoundException e) fileExists = false; String status = null; String conType = null; String content = null; String contentLength = error; if(fileExists) status = HTTP/1.0 200 OK + CRLF; conType = Content-Type: + ContentType(fileName) + CRLF; contentLength = Content-Length : + (new Integer(fis.available().toString() + CRLF; else status = HTTP/1.0 404 NOT Found + CRLF; conType = text/html+ CRLF; content = + 404 Not Found + 404 Not Found + fName+ERROR; 判断文件类型代码:private static String ContentType(String fileName) if(fileName.endsWith(.htm)|fileName.endsWith(.html)return text/html;else if(fileName.endsWith(.jpeg)|fileName.endsWith(.jpg)|fileName.endsWith(.jpe)return image/jpeg;else if(fileName.endsWith(.gif)return image/gif;else return fName; Client端主要代码: Socket生成: Socket clientSocket = new Socket(,8000); Read和write流: OutputStream os = clientSocket.getOutputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream();(4) 遇到的问题及解决方案在编写程序时不能完全读出从客户端(web浏览器)的请求报头。解决方案:在读取客户端请求时用while循环将所有报头信息读出。while(true) request = inFromClient.readLine(); if (request.equals() break; System.out.println(request); 2. 编写多线程Web服务器;(1) 实践内容编写简单的多线程 HTTP 1.0服务器程序(2) 实现过程实现多线程socket程序的流程:开始Socket生成线程1接受连接请求连通关闭线程2接受连接请求连通关闭开始Socket生成连通关闭开始Socket生成连通关闭ConnectConnectReadWriteReadWrite客户端请求1 多线程socket服务端 客户端请求2l 注意: 具体体现出多线程的设计方法,体现出多线程在设计类的时候与单线程的不同; 最好利用UML的类图或结构化的程序流程图来描述程序的实现过程;(3) 关键技术while(true)s = serSocket.accept();ThreadServer currentThread = new ThreadServer();System.out.print(CRLF);System.out.println(线程 + currentThread.getId() +在运行);currentThread.setSocket(s);currentThread.run();当客户端还有请求时,服务端就会新建一个线程处理去处理,当此次请求处理完毕后线程会自己关闭当前socket连接。public void run() try String clientSentence ; BufferedReader inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream() ); OutputStream os = socket.getOutputStream(); clientSentence = inFromClient.readLine(); System.out.println(客户端的请求:+clientSentence); String request; while(true) request = inFromClient.readLine(); if (request.equals() break; System.out.println(request); StringTokenizer s = new StringTokenizer(clientSentence); String temp = s.nextToken(); String fName = null; if(temp.equals(GET) String fileName = s.nextToken(); fName = fileName.substring(0); fileName = . + fileName; FileInputStream fis = null; boolean fileExists = true; try fis = new FileInputStream(fileName); catch(FileNotFoundException e) fileExists = false; String status = null; String conType = null; String content = null; String contentLength = error; if(fileExists) status = HTTP/1.0 200 OK + CRLF; conType = Content-Type: + ContentType(fileName) + CRLF; contentLength = Content-Length : + (new Integer(fis.available().toString() + CRLF; else status = HTTP/1.0 404 NOT Found + CRLF; conType = text/html+ CRLF; content = + 404 Not Found + 404 Not Found + fName+ERROR; System.out.println(服务器的应答:); System.out.print(status); System.out.print(conType); System.out.print(contentLength); if(fileExists) try sendBytes(fis,os); fis.close(); catch (Exception e) e.printStackTrace(); else os.write(content.getBytes(); try os.close(); inFromClient.close(); socket.close(); catch(Exception e) e.printStackTrace(); catch(IOException ioe) ioe.printStackTrace(); l 关键写出在完成各个功能时所使用的具体函数,但不要将全部程序代码粘贴;(4) 遇到的问题及解决方案在线程结束后处理新线程的时候遇到问题,本打算在线城池里先建好3个线程循环使用,在判定线程是否繁忙的时候老是卡住了,后来改成了每次使用新建一个线程,用完后直接关闭该线程。3. 编写RMI程序;(1) 实践内容编写 RMI 程序用 RMI 构建一个分布式共享会议议程服务。不同的客户应该能够使用共享会议议程服务,该服务提供会议的查询、增加和删除功能。会议议程服务器有允许用户注册和撤销会议的功能。(2) 实现过程(二)RMI(Remote Method Invocation,远程函数调用)的工作过程使用 RMI 通信的系统一般分为两类客户端和服务器,服务器提供 RMI 服务,客户端调用服务对象的方法。RMI 服务器必须通过 loopup 服务注册,这样客户才能找到 RMI服务器提供的服务。一旦 RMI 服务器注册,该服务器就等待客户端发送的 RMI 请求。RMI 客户发送 RMI 消息调用远端的对象的方法,在调用任何远端对象之前,客户端必须有一个远端对象的索引,一旦获得远端对象的索引,客户端就可以和远端服务交互了。客户/服务器 RMI 交互过程如图所示。客户/服务器 RMI 交互过程客户端和远端服务的交互是通过 RMI 系统中的 stub 和 skeleton 对象来实现的。Stub对象像一个代理对象,传递客户请求给 RMI 服务器。skeleton 对象负责监听传递过来的RMI 请求并且把这些请求传递给 RMI 服务。stub 对象和 skeleton 对象之间的通信通过TCP 的 Socket 进行。l 注意: 具体体现RMI的交互流程; 在此实践中类的设计、某些功能模块的实现流程; 最好利用UML的类图或结构化的程序流程图来描述程序的实现过程;(3) 关键技术定义 RMI 服务接口的主要方法函数public interface UserList extends Remotepublic void addUser(String name,String pwd)throws RemoteException;public boolean checkPwd(String name,String pwd)throws RemoteException;public String addMeeting(String meetingId,String holder,String attender,String start,String end)throws RemoteException;public void clearMeeting(String name)throws RemoteException;public String queryMeeting(String name,String start,String end)throws RemoteException;public void deleteMeeting(String name,String meetingId)throws RemoteException;public boolean exist(String name)throws RemoteException;public String getUserNames()throws RemoteException; 实现 RMI 服务接口的主要方法函数public class Meeting extends UnicastRemoteObject implements Remote private static final long serialVersionUID = 1L;private String holder;private String attender;private String id=; private String start;private String end;public Meeting()throws RemoteExceptionpublic Meeting(String meetingId,String holder,String attender,String start,String end)throws RemoteExceptionpublic String getId() throws RemoteExceptionboolean checkTime(String s)throws RemoteExceptionpublic String getStart()throws RemoteExceptionpublic String getEnd()throws RemoteExceptionpublic String getAttender()throws RemoteExceptionpublic String getHolder()throws RemoteException 创建 Stub 和 Skeleton 类的主要方法函数Stub 类和 Skeleton 类分别负责分发和处理 RMI 请求,但是开发者不能创建这些类。一旦远程服务存在,可以使用 rmic 工具来创建 Stub 类和 Skeleton 类。public class User extends UnicastRemoteObject implements Remoteprivate static final long serialVersionUID = 1L;private String userName;private String pwd;private VectorholdMeetings=new Vector();private VectorinvitedMeetings=new Vector();Meeting temp;public User(String name,String password)throws RemoteExceptionpublic boolean checkPwd(String password)public boolean checkTime(String start,String end)public void addHoldMeeting(Meeting meeting)public void addInvitedMeeting(Meeting meeting)public void clearInvitedmeeting(Vector meetings)public void clearHoldMeeting()public String getName()public VectorgetHoldMeetings()public VectorgetInvitedMeetings()public Meeting getHoldMeeting(String name)public void deleteHoldMeeting(String meeting)public void deleteInvitedMeeting(String meeting)public class UserListImpl extends UnicastRemoteObject implements UserList Vectorusers=new Vector(); public UserListImpl()throws RemoteExceptionpublic void addUser(String name,String pwd)throws RemoteExceptionpublic User getUser(String name)public boolean exist(String name)throws RemoteExceptionpublic boolean checkPwd(String name,String pwd)throws RemoteExceptionpublic String addMeeting(String meetingId,String holder,String attender,String start,String end)throws RemoteExceptionpublic void clearMeeting(String name)throws RemoteExceptionpublic String queryMeeting(String name,String start,String end)throws RemoteExceptionpublic void deleteMeeting(String name,String meetingId)throws RemoteException 创建 RMI 服务器程序主要代码public class MeetingServerpublic static void main(String args)tryLocateRegistry.createRegistry(8000); UserList userList=new UserListImpl();Naming.rebind(rmi:/:8000/users, userList);catch(Exception e)System.out.println(e.getMessage();创建 RMI 客户端程序主要代码public class MeetingClientpublic static void main(String args)String url=rmi:/:8000/;System.out.println(你好);tryUserList ul=(UserList)Naming.lookup(url+users);while(true)System.out.println(请依照以下命令格式:);System.out.println(用户注册:registerusernamepassword);System.out.println(增加会议:addusernamepasswordotherusernamestartTime【hour:minute】endTime【hour:minute】title);System.out.println(查询会议:queryusernamepasswordstartTime【hour:minute】endTime【hour:minute】);System.out.println(删除会议:deleteusernamepasswordmeetingID);System.out.println(清除会议:clearusernamepassword);BufferedReader br=new BufferedReader(new InputStreamReader(System.in);String input=;int tem=0;while(tem=br.read()!=n&tem!=r)input+=(char)tem;Stringpra=new String7;StringTokenizer stn=new StringTokenizer(input);int con=0;while(stn.h

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论