UDP协议实现ICMP协议中的Ping报文

原理:

采用UDP协议来实现ICMP协议中的Ping报文功能,就必须在应用层来模拟网格层中的Ping报文的工作流程,即首先由客户机向服务器段发送一个应用层的UDP Ping请求报文,在服务器段程序接收到UDP Ping请求报文后,就会向客户机返回一个UDP Ping响应报文。客户机通过判断程序中收到的报文及其相关的信息可以判断链路状况。

流程图:

在这里插入图片

编写服务器段程序
功能:

1.根据用户输入参数打开特定的插口,并对插口进行监听,
2.接受从客户机发送过来的应用层Ping请求报文并打印
3.向客户机回复Ping响应报文

import java.io.*;
import java.net.*;
import java.nio.channels.NonWritableChannelException;
import java.util.*;
public class PingServer {
	private static final double LOSS_RATE=0.3;
	private static final int AVERAGE_DELAY=100;
	public static void main(String[] args)throws Exception {
		if(args.length!=1) {
			System.out.println("Required arguments:port");
			return;
		}
		int port = Integer.parseInt(args[0]);
		Random random = new Random();
		DatagramSocket socket = new DatagramSocket(port);
		while(true) {
			DatagramPacket requset=new DatagramPacket(new byte[1024], 1024);
			socket.receive(requset);
			printData(requset);
			if(random.nextDouble()<LOSS_RATE) {
				System.out.println("Reply not sent");
				continue;
			}
			Thread.sleep((int)(random.nextDouble()*2*AVERAGE_DELAY));
			InetAddress clientHost=requset.getAddress();
			int clientPort = requset.getPort();
			byte[] buf = requset.getData();
			DatagramPacket reply= new DatagramPacket(buf, buf.length,clientHost,clientPort);
			socket.send(reply);
			System.out.println("Reply sent");
		}
	}
	private static void printData(DatagramPacket requset) throws Exception {
		// TODO Auto-generated method stub
		byte[] buf = requset.getData();
		ByteArrayInputStream bais=new ByteArrayInputStream(buf);
		InputStreamReader isr= new InputStreamReader(bais);
		BufferedReader br=new BufferedReader(isr);
		String line = br.readLine();
		System.out.println("Received from"+ requset.getAddress().getHostAddress()+"."+new String(line));
	}
}
编写客户机程序
功能

1.与服务器建立连接构建UDP Ping请求报文
2.将请求报文发送给服务器 同时等待和接收服务器发回的响应报文,连续发10次Ping命令后关闭插口

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;
public class PingClient {
	public static void main(String[] args)throws Exception {
		if(args.length==0) {
			System.out.println("Required argument:Host port");
			return;
		}
		if(args.length==1) {
			System.out.println("Required argument: port");
			return;
		}
		String host=args[0].toString();
		int port = Integer.parseInt(args[1]);
		DatagramSocket clientSocket = new DatagramSocket();
		clientSocket.setSoTimeout(1000);
		InetAddress IPAddress=InetAddress.getByName(host);
		long sendTime,receiveTime;
		for(int i=0;i<10;i++) {
			byte[] sendData=new byte[1024];
			byte[] receviceData=new byte[1024];
			Date currentTime=new Date();
			SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String timeStamp= formatter.format(currentTime);
			String pingMessage= "Ping"+"i"+""+timeStamp+""+"\r\n";
			sendData = pingMessage.getBytes();
			DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length,IPAddress,port);
			try {
				sendTime = System.currentTimeMillis();
				clientSocket.send(sendPacket);
				DatagramPacket receivePacket = new DatagramPacket(receviceData, receviceData.length);
				clientSocket.receive(receivePacket);
				receiveTime =System.currentTimeMillis();
				long latency= receiveTime-sendTime;
				String serverAddress= receivePacket.getAddress().getHostAddress();
				System.out.println("From"+serverAddress + ":"+latency+"ms.");
			}catch(java.net.SocketTimeoutException ex){
				String reply="No reply";
				System.out.println(reply);
			}
		}
		clientSocket.close();
	}
}
效果复现:

找到对应java文件的编译文件,进入PowerShell使用CMD命令执行对应语句:
首先开发一个端口号80
在这里插入图片描述
然后再开一个PowerShell窗口执行ServerClient.java 127.0.0.1 80
在这里插入图片描述
此时服务器部分:
在这里插入图片描述
大功告成!!!!!!

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值