zoukankan      html  css  js  c++  java
  • 计算机网络- 可靠数据传输协议-设计和实施的协议,如停止的

    一、停等协议,实现一个简单的介绍

    我设计的程序实现的是rdt3.0停止的其他协议的版本号,的数据包发送方01交替的顺序发送数据包。当发送0数据包之后開始计时,仅仅有接收到ack0才干继续发送1数据包。假设在没有接收到ack0的时候已经超时,这时候须要重传数据包0

    接收方依照所收到的数据包的编号返回对应的ack,当上一个收到的是数据包0后下一个仅仅有是数据包1才干接收放到接收文件里,假设下一个还是数据包0那么就要丢弃。

     

    二、分组格式

    数据报格式:

     

      

     

    三、UDP编程的特点

    UDP协议是无连接的数据传输格式。所以就不用像tcp一样建立专门的socket连接特定的主机在数据传输,而是将每一个数据包打包后将目的主机的host和port号加入到数据包中之后就发送出去,而不提供不论什么的保持连接。

    所以使用UDP编程就是以包的形式在DatagramSocket中传送和接受。在java中数包能够用datagramPacket()加上指定的host和port而构成。之后就由datagramSocket()发送出去即可,对应的接收也是在以监听某接口的datagramSocket(****)接收包,在依照自定义的数据包的格式提取出不同部分的实用信息即可。

    四、实验实现的主要类及其作用

    主要类:

    server()类:实现服务器功能。接受数据包,解析后将有效信息输出到接收文件,返回对应数据包的ACK

    Client()类:实现client功能,从发送文件里读取信息,依照数据报的定义组合成一个个的数据报。向server发送数据包同一时候计时,而且控制超时、返回ack不是想要的等各种情况的对应处理。

    实验中server和client都是以线程的形式启动。其接受和发送数据包在各自的run()方法中实现。

    五、实验验证结果

    模拟丢失ACK。会有超时重传:

     

    数据传送完成:read文件为发送的,receive为接收文件

     




    package rdt;
    import java.net.*;
    import java.io.*;
    
    public class Server extends Thread{
    	public static final int MAX_LENGTH = 1024;
    	public static DatagramSocket socket;
    	public static int last;	//上一次收到的包的编号
    	public static byte[] receive = new byte[MAX_LENGTH];
    	public static byte[] send = new byte[MAX_LENGTH];
    	public static OutputStream writeFile;
    	public static InetAddress inetAddress;
    	public static int port;
    	
    	public Server() {
    		try {
    			socket = new DatagramSocket(8888);
    			last = 1;	//由于第一个须要的是0号packet
    			writeFile = new FileOutputStream("receive.txt"); 
    			receive[0] = 1;
    		} catch (SocketException e) { 
    			e.printStackTrace();
    		} catch (FileNotFoundException e) { 
    			e.printStackTrace();
    		}  
    	}
    	public void run() {
    		int timeOut = 0;	//模拟最多超时的次数,之后恢复
    		while(true) {
    		try{
    		DatagramPacket packet1 = new DatagramPacket(receive,receive.length);
    		socket.receive(packet1);
    		byte order = receive[0]; 
    		byte need = (byte)((last==0)?

    1:0); System.out.println("收到的数据包是:"+order+" 须要的是:"+need); //收到的是须要的数据包。则写入文件。回传ack if(need == order) { writeFile.write(receive, 1, packet1.getLength()-1); send[0] = need; last = order; System.out.println("回传的ack是:"+need); inetAddress = packet1.getAddress(); port = packet1.getPort(); System.out.println("主机名:"+inetAddress.getHostName()+" port:"+port); DatagramPacket packet2 = new DatagramPacket(send,send.length,inetAddress,port); if(timeOut++ > 1){ socket.send(packet2); } } else{ send[0] = order; System.out.println("传回来的包不是想要的。丢弃。

    。"); System.out.println("回传的ack是:"+need); inetAddress = packet1.getAddress(); port = packet1.getPort(); System.out.println("主机名:"+inetAddress.getHostName()+" port:"+port); DatagramPacket packet2 = new DatagramPacket(send,send.length,inetAddress,port); socket.send(packet2); } } catch (IOException e) { e.printStackTrace(); } } } }




    package rdt;
    import java.net.*;
    import java.io.*;
    
    public class Client extends Thread{
    	public static int MAX_LENGTH = 1024;	//每次读取文件的的最大字节数
    	public static final int TIMEOUT = 3000; //设置超时时间	 
    	public static byte[] receive = new byte[MAX_LENGTH];
    	public static DatagramSocket socket;
    	public static InputStream inputFile = null; //从这读取传送数据
    	public static byte order;
    	public static InetAddress inetAddress;
    	public static int port;
    	 
    	public Client () {
    		 try { 
    			 socket = new DatagramSocket();
    			 socket.setSoTimeout(TIMEOUT);
    			inputFile = new FileInputStream("read.txt");
    			order = 0;	//刚開始发送的是0数据包
    			inetAddress =  InetAddress.getByName("localhost");
    			port = 8888;
    		} catch (SocketException | FileNotFoundException e) { 
    			e.printStackTrace();
    		} catch (UnknownHostException e) { 
    			e.printStackTrace();
    		}	 
    	}
    	public void run() {
    		int count = 0; 
    		 //创建数据包
    		while(true) {  
    			int len;
    			try { 
    				byte[] sendata = new byte[MAX_LENGTH];
    				sendata[0] = order; 
    				len = inputFile.read(sendata,1,sendata.length-1);
    				count++;
    				System.out.println(len);
    				if(len == -1)	//文件已经传送完成
    					break;
    				while(len != -1) { 
    					try{
    					DatagramPacket packet = new DatagramPacket(sendata,len,inetAddress,port);
    					socket.send(packet); 
    					System.out.println("发送第"+count+"个数据报");
    					DatagramPacket packet2 = new DatagramPacket(receive,receive.length);
    					socket.receive(packet2);
    					byte ack = receive[0];
    					System.out.println("传出去的包是:"+order+"传回来的ACK是:"+ack);
    					if(ack == order) {
    						order = (byte) ((order==0)?

    1:0); break; //转到下一个转态 } //否则重传 }catch(SocketTimeoutException e) { //超时。须要重传 System.out.println("超时,重传"); } } } catch (IOException e) { e.printStackTrace(); } } } }



    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    JAVA抽象方法,接口
    JAVA基础,字符串
    JAVA运算符
    JAVA数组
    团队任务1:第一次团队会议
    课后作业二:个人项目
    自我介绍
    python3加密 解密 签名 验签
    python3读取xml字符串
    SETX命令设置环境变量
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4793665.html
Copyright © 2011-2022 走看看