4编程实现基于UDP的PING.docx

上传人:b****8 文档编号:28079132 上传时间:2023-07-08 格式:DOCX 页数:15 大小:21.75KB
下载 相关 举报
4编程实现基于UDP的PING.docx_第1页
第1页 / 共15页
4编程实现基于UDP的PING.docx_第2页
第2页 / 共15页
4编程实现基于UDP的PING.docx_第3页
第3页 / 共15页
4编程实现基于UDP的PING.docx_第4页
第4页 / 共15页
4编程实现基于UDP的PING.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

4编程实现基于UDP的PING.docx

《4编程实现基于UDP的PING.docx》由会员分享,可在线阅读,更多相关《4编程实现基于UDP的PING.docx(15页珍藏版)》请在冰豆网上搜索。

4编程实现基于UDP的PING.docx

4编程实现基于UDP的PING

计算机网络课程设计

课程名称计算机网络课程设计

学院计算机学院

专业班级

学号

学生姓名

指导教师梁路

年月日

计算机网络课程设计任务书

设计题目

编程实现基于UDP的PING(Java)

已知技术参数和设计要求

1.编程实现PING的服务器端和客户端,实现操作系统提供的ping命令的类似功能。

2.服务器端PingServer功能:

2.1可以并发地为多个用户服务;

2.2显示用户通过客户端发送来的消息内容(包含头部和payload);

2.3能够模拟分组的丢失;能够模拟分组传输延迟;

2.4将用户发送来的请求request在延迟一段随机选择的时间(小于1s)后返回给客户端,作为收到请求的响应reply;

2.5通过如下命令行启动服务器:

javaPingServerport。

port为PingServer的工作端口号

3.客户端PingClient功能:

3.1启动后发送10个request。

发送一个request后,最多等待1秒以便接收PingServer返回的reply消息。

如果在该时间内没有收到服务器的reply,则认为该请求或对该请求的reply已经丢失;在收到reply后立即发送下一个request。

3.2请求消息的payload中至少包含关键字PingUDP、序号、时间戳等内容。

如:

PingUDPSequenceNumberTimeStampCRLF

其中:

CRLF表示回车换行符(0X0D0A);TimeStamp为发送该消息的机器时间。

3.3为每个请求计算折返时间(RTT),统计10个请求的平均RTT、最大/小RTT。

3.4通过如下命令行启动:

javaPingClienthostport。

host为PingServer所在的主机地址;port为PingServer的工作端口号

设计内容与步骤

1.学习ICMP,了解ping命令的工作机理;

2.学习JavaUDPSocket通信机制;

3.了解Java多线程程序设计;

4.服务器PingServer程序设计;

5.客户端PingClient程序设计。

6.调试与演示

设计工作计划与进度安排

1.ping命令工作机制学习2小时

2.JavaUDPSocket通信机制2小时

3.Java多线程程序设计4小时

4.PingServer程序设计6小时

5.PingClient程序设计12小时

6.调试与演示4小时

6.课程设计说明书10小时

目录:

1.基础知识:

1.1.ICMP

ICMP是(InternetControlMessageProtocol)Internet控制报文协议。

它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。

控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。

这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。

ICMP协议是一种面向无连接的协议,用于传输出错报告控制信息。

它是一个非常重要的协议,它对于网络安全具有极其重要的意义。

1.2.Ping

PING?

是DOS命令,一般用于检测网络通与不通?

,也叫时延,其值越大,速度越慢?

?

?

PING?

(Packet?

Internet?

Grope),因特网包探索器,用于测试网络连接量的程序。

Ping发送一个ICMP回声请求消息给目的地并报告是否收到所希望的ICMP回声应答。

?

?

?

?

它是用来检查网络是否通畅或者网络连接速度的命令。

作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS命令,它所利用的原理是这样的:

网络上的机器都有唯一确定的IP地址,我们给目标IP地址发送一个数据包,对方就要返回一个同样大小的数据包,根据返回的数据包我们可以确定目标主机的存在,可以初步判断目标主机的操作系统等。

?

?

?

Ping?

是Windows系列自带的一个可执行命令。

利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障。

应用格式:

Ping?

IP地址。

该命令还可以加许多参数使用,具体是键入Ping按回车即可看到详细说明。

ping指的是端对端连通,通常用来作为可用性的检查?

?

1.3.UDP

UDP是UserDatagramProtocol的简称,中文全称是用户数据包协议,是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

在网络中它与TCP协议一样用于处理数据包。

在OSI模型中,UDP协议在第四层——传输层,处于IP协议的上一层。

与TCP相比,UDP有不提供数据报分组、组装和不能对数据包的排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。

UDP用来支持那些需要在计算机之间传输数据的网络应用。

(1)UDP是一个无连接协议

(2)由于传输数据不建立连接,因此也就不需要维护连接状态,包括收发状态等,因此一台服务机可同时向多个客户机传输相同的消息。

(3)UDP信息包的标题很短,只有8个字节

(4)吞吐量不受拥挤控制算法的调节,只受应用软件生成数据的速率、传输带宽、源端和终端主机性能的限制。

(5)UDP使用尽最大努力交付,即不保证可靠交付

(6)UDP是面向报文的。

发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付给IP层。

既不拆分,也不合并,而是保留这些报文的边界,因此,应用程序需要选择合适的报文大小

1.4.多线程:

Java中创建线程有两种方法:

使用Thread类和使用Runnable接口。

在使用Runnable接口时需要建立一个Thread实例。

因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例。

Java中关于线程调度的API最主要的有下面几个:

线程睡眠:

Thread.sleep(longmillis)方法

线程等待:

Object类中的wait()方法

线程让步:

Thread.yield()方法

线程加入:

join()方法

线程唤醒:

Object类中的notify()方法

2.设计思路:

2.1.线程设计:

(1)获取从服务其传送到的请求报文的数据,将原报文内的数据封装进一个新的DatagramPacket中。

(2)选取处于0-1500之间的随机数,作为睡眠时间。

(3)睡眠时间结束后,开始向获取到的客户端的地址和端口发送封装好的DatagramPacket

2.2.服务器设计:

(1)定义一个UDP的DatagramSocket传送数据,记录服务器启动的时间

(2)进入死循环,不断监听是否有客户端传送来的请求报文,若有,转(3)

(3)计算当前时间与服务器启动时间的差值,若差值处于5秒到5.5秒之间,返回

(2)(模拟分组丢失);否则启动新线程

2.3.客户端设计:

(1)定义一个UDP的DatagramSocket传送数据。

(2)将关键字PingUDP,序号和时间戳封装到DatagramPacket中作为报文的内容。

(3)向服务器的制定端口发送封装好的报文信息

(4)设置超时计时器

(5)超过超时计时器的时间未收到服务器发来的响应报文,则返回

(2);否则,转(5)

(6)判断接收到的报文是否与当前发送的报文相对应,若是,返回

(2);否则,返回(5)。

3.程序流程图:

3.1.Java线程程序流程图:

3.2.PingServer程序流程图:

3.3.PingClient程序流程图:

4.代码:

4.1.线程代码:

/**

*

*/

ion;

/**

*线程

*@authorLingHuacai

*

*/

publicclassThreadServerextendsThread{

privateDatagramSocketsocket;

privateDatagramPacketpacket;

publicThreadServer(DatagramSocketsocket,DatagramPacketpacket){

//初始化socket和packet

this.socket=socket;

this.packet=packet;

}

publicvoidrun(){

//定义延迟回送报文的随机时间

longrandomTime=(long)(Math.random()*1500);

Stringdata=newString(packet.getData());

byte[]buffer=data.getBytes();

//获取客户端地址

InetAddresshost=packet.getAddress();

//获取客户端应用进程端口号

intport=packet.getPort();

//回送给客户端的报文

DatagramPacketsend=newDatagramPacket(buffer,buffer.length,host,port);

try{

sleep(randomTime);

}catch(InterruptedExceptione){

e.printStackTrace();

}

try{

//回送报文

socket.send(send);

}catch(IOExceptionee){

ee.printStackTrace();

}

}

}

4.2.服务器端代码:

/**

*

*/

packageudp;

import

import

import

importjava.net.SocketException;

/**

*服务器端

*@authorLingHuacai

*

*/

publicclassPingServerextendsThread{

//监听的端口号

privateintinitPort;

privatebyte[]buf=newbyte[32];

privateDatagramPacketpacket;

privateDatagramSocketsocket;

publicPingServer(intinitPort){

this.initPort=initPort;

}

publicvoidrun(){

try{

//初始化socket,定义socket的端口号

socket=newDatagramSocket(initPort);

System.out.println("Serverstarted");

}catch(SocketExceptione){

System.out.println("监听端口"+initPort+"失败");

e.printStackTrace();

//初始化端口号失败,终止程序

System.exit(0);

}

//记录当前时间

longstartTime=System.currentTimeMillis();

//死循环,不断监听是否有报文请求

while(true){

try{

packet=newDatagramPacket(buf,buf.length);

//获取客户端发来的报文

socket.receive(packet);

}catch(IOExceptione){

e.printStackTrace();

}

//输出分组和服务器启动时间的差值

System.out.println("接收到这个分组的的时间与服务器启动时间差:

"+(System.currentTimeMillis()-startTime)+"毫秒!

");

if(5000>(System.currentTimeMillis()-startTime)||

(System.currentTimeMillis()-startTime)>5500){

ThreadServerserver=newThreadServer(socket,packet);

//启动线程

server.start();

}

}

}

publicvoiddestroy(){

socket.close();

}

publicstaticvoidmain(String[]args){

//初始化服务器

PingServerping=newPingServer(Integer.valueOf(args[0]));

ping.start();

}

}

4.3.客户端代码:

/**

*客户端

*@authorLingHuacai

*

*/

publicclassPingClientextendsThread{

privateDatagramSocketclient;

privateInetAddresshostAddress;

intport;

//定义并初始化接收到的响应报文的个数

intj=0;

//定义并初始化最小往返时间,最大往返时间,平均往返时间

longminRtt=0,maxRtt=0,avrRtt=0,sumRtt=0;

long[]rtt=newlong[10];

publicPingClient(Stringhost,intport){

this.port=port;

try{

client=newDatagramSocket();

//获取客户端地址

hostAddress=InetAddress.getByName(host);

}catch(UnknownHostExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}catch(SocketExceptionee){

ee.printStackTrace();

}

}

publicvoidrun(){

//定义时间戳格式

SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddhh:

mm:

ss.SS");

for(inti=0;i<10;i++){

rtt[i]=0;

}

for(inti=0;i<10;i++){

//发送报文中的时间

DatesendTime=newDate();

StringoutMessage=newString("PingUDP:

"+i+","+sdf.format(sendTime));

Stringrecieve=null;

byte[]buffer=outMessage.getBytes();

byte[]buf=newbyte[buffer.length];

DatagramPacketsendPacket=newDatagramPacket(buffer,buffer.length,hostAddress,port);

DatagramPacketrecievePacket=newDatagramPacket(buf,buf.length);

try{

client.send(sendPacket);

//设置超时时间为1秒

client.setSoTimeout(1000);

//接收响应报文

client.receive(recievePacket);

recieve=newString(recievePacket.getData());

//判断是否为延时报文,若为延时报文则丢弃,继续接收报文

while(!

recieve.equals(outMessage)){

recieve=null;

client.receive(recievePacket);

recieve=newString(recievePacket.getData());

}

//记录接收后时间

DaterecieveTime=newDate();

//计算往返时间

rtt[i]=recieveTime.getTime()-sendTime.getTime();

}catch(IOExceptione){

//TODOAuto-generatedcatchblock

e.printStackTrace();

}

if(recieve!

=null){

}

}

if(rtt[0]!

=0){

minRtt=rtt[0];

maxRtt=rtt[0];

sumRtt=rtt[0];

j++;

}

elseminRtt=2000;

for(inti=1;i<10;i++){

if(rtt[i]!

=0){

j++;

//计算最小往返时间

if(minRtt>rtt[i]){

minRtt=rtt[i];

}

//最大往返时间

if(maxRtt

maxRtt=rtt[i];

}

//总往返时间

sumRtt=sumRtt+rtt[i];

}

}

if(j!

=0){

//计算平均往返时间

avrRtt=sumRtt/j;

}

else{

}

//关闭线程

client.close();

}

publicstaticvoidmain(String[]args){

PingClientclientThread=newPingClient(args[0],Integer.valueOf(args[1]));

clientThread.start();

}

}

5.编译过程与截图

将PingServer.java文件和PingClient.java文件添加到指定目录中

使用cmd命令(注:

使用的计算机需安装了java的JDK并且能够使用cmd来编译Java程序)编译运行PingServer.java文件和PingClient.java文件过程如下:

(1)输入文件所在的硬盘,如:

C:

(2)使用"cd文件夹名"来打开文件所在的文件夹,如果文件直接存在硬盘之下,则转(3);如果文件的文件夹在另一个文件夹中,则多次输入"cd文件夹名"直到到达文件所在的目录

(3)分别使用cmd来编译文件,cmd命令如下:

javacPingServer.java

javacPingClient.java

服务器端运行截图:

客户端运行截图:

6.课程设计小结

我选择了编程实现基于UDP的PING作为这次的计算机网络课程设计的题目。

原本是打算写链路状态路由算法,看了书上的内容也找了一些资料,可是弄不太懂路由器之间的初始路由表是怎么获得的,于是就选了这个主题,比较明白易懂一点。

但是由于之前没有接触过网络的编程,并不了解网络Socket的使用,所以在编程的时候碰到一些瓶颈。

在设计客户端最多等待1秒接收服务器端返回的信息用的时间最久,本来想是不是应该在PingClient端使用wait()方法来停止时间,使用另一个线程来进行接收服务器端回送的数据,后来想到还有1秒钟这个限制。

想过很多种方法,也尝试过很多方法,一边学习一边编程,了解到DatagramSocket的receive方法是阻塞模式的,原本并不知道阻塞模式是什么。

后来才在网上看到DatagramSocket有SetSoTimeout这个方法可以在一段时间之后抛出一个异常来终止receive的阻塞模式。

通过这次的课程设计,我了解了一点有关网络编程的基本知识,对ICMP有了更深刻的了解。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 图表模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1