码迷,mamicode.com
首页 > 其他好文 > 详细

计算机网络- 可靠数据传输协议-停等协议的设计与实现

时间:2015-06-05 00:43:15      阅读:779      评论:0      收藏:0      [点我收藏+]

标签:http协议   计算机网络   可靠数据传输   停等协议   

一、所实现停等协议简介

我设计的程序实现的是rdt3.0版本的停等协议,发送端将数据包以01交替的顺序发送数据包,当发送0数据包之后开始计时,只有接收到ack0才能继续发送1数据包,如果在没有接收到ack0的时候已经超时,这时候需要重传数据包0

接收方按照所收到的数据包的编号返回相应的ack,当上一个收到的是数据包0后下一个只有是数据包1才能接收放到接收文件中,如果下一个还是数据包0那么就要丢弃。

 

 技术分享

二、分组格式

数据报格式:

 技术分享

  

 技术分享

 

三、UDP编程的特点

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

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

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

主要类:

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

Client()类:实现客户端功能,从发送文件中读取信息,按照数据报的定义组合成一个个的数据报,向服务器发送数据包同时计时,并且控制超时、返回ack不是想要的等各种情况的相应处理。

实验中服务器和客户端都是以线程的形式启动,其接受和发送数据包在各自的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();
			} 
			}
		}
	} 


 

计算机网络- 可靠数据传输协议-停等协议的设计与实现

标签:http协议   计算机网络   可靠数据传输   停等协议   

原文地址:http://blog.csdn.net/ymzmdx/article/details/46369835

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!