44实验9:利用Java开发网络应用程序1.实验目的1)基本掌握利用Java开发环境调试应用程序的方法。2)理解基于套接字开发网络应用程序的过程,深入理解Ping工作原理。3)深入理解HTTP协议的格式和工作过程,理解Web代理服务器工作原理。2.实验环境1)运行Windows2008Server/WindowsXP/Windows7操作系统的PC2台。2)每台PC具有以太网卡一块,通过双绞线与局域网相连。3)具有Java开发包jdk-1_5_0_06-windows-i586-p.exe。3.实验步骤1)安装Java编程环境(1)安装开发包JDK。双击JDK安装程序jdk-1_5_0_06-windows-i586-p.exe图标,进行安装。根据安装提示选择安装目录后开始安装过程。在安装JDK的过程中,同时需要安装Java运行环境JRE(JavaRuntimeEnvironment)。接下来。配置Java环境变量。右键点击“我的电脑”,选择“属性”。然后选择“高级”选项卡,点击“环境变量”,即弹出如图45所示的界面。图45环境变量配置界面(2)修改环境变量的值。在“用户变量”中,分别设置JAVA_HOME、PATH和CLASSPATH这3项属性。若已存在则点击“编辑”,不存在则点击“新建”。45JAVA_HOME指明JDK的安装路径,也就是在安装时选择的路径,如D:\Java\jdk1.5.0_06,在此路径下包括lib、bin、jre等文件夹。PATH使得系统可以在任何路径下识别Java命令,该值设为“%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin”。CLASSPATH为Java加载类路径,只有类在classpath中,Java命令才能识别,该值设为“.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar”。测试安装结果。选择“开始”菜单中的“运行”,键入“cmd”。在命令提示符中键入“java–version”、“java”和“javac”命令,出现如图46所示画面则说明环境变量配置成功。图46运行Java命令结果(3)在命令提示符环境编译运行java程序。Java程序编写后,就可以在命令提示符环境下编译和运行。启动命令提示符后,先利用“cd”命令进入Java程序所在的目录,然后键入“javacjava类的文件名”命令编译该Java程序。如果编译成功,则不会显示错误信息并直接返回。此后,在该目录下会产生一个.class文件。直接键入“javajava类名运行参数”即可运行该编译好的Java程序。如果想要退出正在运行的Java程序,按“ctrl+C”即可完成。2)在Java集成开发环境下调试程序前面假定编写的Java程序是正确的,而事实上自己首次编写的程序通常都会出现这样或那样的问题。为此,需要借助于Java集成开发环境来调试程序。(1)安装Java集成开发环境。Java的集成开发环境有很多,对于IBM公司开发的开源Java集成开发环境eclipse,在解压eclipse压缩包后,双击eclipse.exe即可运行eclipse。图49是eclipse运行后的主界面。46图49eclipse集成开发环境主界面(2)在eclipse中创建、编译和运行java程序。首先要创建java程序。运行eclipse后,从菜单栏选择“File-New-Project…”,接着会弹出如图50所示的对话框。图50eclipse新建项目向导在下拉框中选中“JavaProject”,点击下方的“Next”按钮,弹出“NewJavaProject”向导,在“Projectname”中输入如“Example”,点击“Finish”按钮关闭对话框,这样一个java项目就建立完毕了,同时在eclipse的左侧会出现新建好的名为“Example”的java项目。接下来右键点击“Example”项目,选择“New-class”,弹出如图51所示的新建类java对话框。47图51eclipse新建类向导在“Name”中输入需要新建的类的名字,点击下方的“Finish”按钮即可创建一个新的java类。然后再编译和运行java程序。在eclipse右侧的程序编辑框中编写完java程序后,点击菜单栏中的“保存”,eclipse会自动对代码进行编译并生成类文件。在编译完java代码后,即可运行写好的类,右键选择需要运行的java类,选择“RunAs-Run…”。选择“Arguments”选项卡,在“Programarguments”中输入程序运行参数,然后点击下方的“Run”按钮,即可运行该java程序。483)编写UDPPing程序要采用UDP协议来实现ICMP协议中Ping报文的功能,就必须在应用层来模拟网络层中Ping报文的工作流程,即首先由客户机向服务器端发送一个应用层的UDPPing请求报文,服务器端程序在接收到UDPPing请求报文后,向客户机返回一个UDPPing响应报文,客户机通过判断是否能够接收到该响应报文以及相应的丢包率、时延大小等信息来分析客户机与服务器端之间的链路状况。因此需要利用UDP套接字实现服务器和客户机程序,在应用层模拟Ping报文的通信过程。图54显示了服务器和客户机之间的交互过程。图54服务器和客户机交互过程(1)编写服务器端程序。服务器端程序主要实现的功能包括:根据用户输入参数打开特定的插口,并对插口进行监听,接收从客户机发送过来的应用层Ping请求报文,打印该应用层数据内容,然后向客户机回复Ping响应报文。请学员阅读代码并回答下列问题:1)代码第16行为什么要加上port参数?不加该参数会出现什么情况?16行的Port参数用于标识进程,因为UDP是进程到进程之间的通信,如果没有,则无法识别报文的目的是否自己。2)哪一行代码是用于接收客户机发送过来的Ping请求报文?19行用于接收客户机发送过来的ping报文。3)代码第21至24行是模拟网络中的什么现象?21~24模拟了网络丢包现象。4)代码第25行又是模拟网络中的什么现象?25行模拟了网络出现时延。5)代码第26和27行所获取的参数分别代表什么意思?不提取该参数行不行?为什么?26、27行获取客户机进程的地址和端口,如果不提取参数,就无法49发送报文到客户机进程。6)服务器端向客户机回复的Ping响应报文应用层数据是什么?服务器端向客户机回复的Ping响应报文应用层数据是客户机发过来的ping报文数据。1importjava.io.*;2importjava.net.*;3importjava.util.*;4/*利用UDP协议实现ping报文请求的服务器端程序*/5publicclassPingServer{6privatestaticfinaldoubleLOSS_RATE=0.3;7privatestaticfinalintAVERAGE_DELAY=100;8publicstaticvoidmain(String[]args)throwsException9{10if(args.length!=1){11System.out.println(Requiredarguments:port);12return;13}14intport=Integer.parseInt(args[0]);15Randomrandom=newRandom();16DatagramSocketsocket=newDatagramSocket(port);17while(true){18DatagramPacketrequest=newDatagramPacket(newbyte[1024],1024);19socket.receive(request);20printData(request);21if(random.nextDouble()LOSS_RATE){22System.out.println(Replynotsent.);23continue;24}25Thread.sleep((int)(random.nextDouble()*2*AVERAGE_DELAY));26InetAddressclientHost=request.getAddress();27intclientPort=request.getPort();28byte[]buf=request.getData();29DatagramPacketreply=newDatagramPacket(buf,buf.length,clientHost,clientPort);30socket.send(reply);31System.out.println(Replysent.);32}33}34/*将ping报文的数据按照标准输出流打印出来*/35privatestaticvoidprintData(DatagramPacketrequest)throwsException36{37byte[]buf=request.getData();38ByteArrayInputStreambais=newByteArrayInputStream(buf);39InputStreamReaderisr=newInputStreamReader(bais);5040BufferedReaderbr=newBufferedReader(isr);41Stringline=br.readLine();42System.out.println(Receivedfrom+request.getAddress().getHostAddress()+:+newString(line));43}44}(2)编写客户机程序客户机程序需要主要实现的功能包括:与服务器建立连接,然后构建UDPPing请求报文,并将其发送给服务器,同时等待和接收从服务器发回的响应报文,连续发送10次Ping请求报文后关闭插口。准备显示了完成上述功能的服务器端代码,请学员阅读代码并回答下列问题:1)用户输入参数应当有多少个?这些参数的所代表的意义是什么?用户输入的参数要有服务器进程地址和端口。2)客户机插口设置的超时时间是多少?为什么要设置超时时间?超时时间为1s,用于模拟出现丢包或时延时采取动作。3)客户机向服务器发送的Ping请求报文应用层数据格式是什么?数据格式为PING+i++timeStamp++\r\n,其中i为当前报文序号,timeStamp为日期和时间。4)代码第30行中四个参数的意义分别是什么?发送报文用到的4个参数为数据、数据长度、服务器进程的地址和端口。5)代码第32、36和37行是为了完成什么功能?32、36、37行用于得到往返时延。6)哪行代码是用于接收服务器发送过来的Ping响应报文?35行用于接收服务器发送过来的ping报文。1importjava.net.DatagramPacket;2importjava.net.DatagramSocket;3importjava.net.InetAddress;4importjava.text.SimpleDateFormat;5importjava.util.Date;6publicclassPingClient{7publicstaticvoidmain(String[]args)throwsException{8if(args.length==0){9System.out.println(Requiredarguments:hostport);10return;11}12if(args.length==1){13System.out.println(Requiredarguments:port);14return;5115}16Stringhost=args[0].toString();17intport=Integer.parseInt(args[1]);18DatagramSocketclient