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

一、所实现停等协议简介

我设计的程序实现的是rdt3.0版本的停等协议,发送端将数据包以0、1交替的顺序发送数据包,当发送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();
			}
			}
		}
	}
时间: 2024-12-28 10:23:08

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

【计算机网络】-传输层-Internet传输协议-TCP

[计算机网络]-传输层-Internet传输协议-TCP TCP介绍 在不可靠的互联网上提供一个可靠的端到端字节流 面向连接的.可靠的.端到端的.基于字节流的传输协议 TCP位置 TCP服务模型 应用程序访问TCP服务 通过在收发双方创建套接字来实现的 套接字的地址 用(IP地址,端口号)来表示的 知名端口 1024以下的端口号,如FTP:21,TELNET:23,SMTP:23 每条连接用(套接字1,套接字2)来表示,是点到点的全双工通道 TCP不支持 多播(multicast)和广播(bro

不务正业 (1) —— 在应用层模拟实用停等协议

[总目录]http://www.cnblogs.com/tbcaaa8/p/4415055.html 1. 背景说明 本文章来源于近期需要提交的<计算机网络>课程实验. 实验分为3部分,分别需要在应用层模拟实用停等协议.连续ARQ协议和滑动窗口协议,实现文件的传输.端与端之间的通信使用Socket完成. 语言可以任选,出于简单,本文以java为例,仅介绍使用停等协议的实现,其他内容由同学们自己探索吧.强烈不推荐MFC,除非想把自己玩死. 注:本人上课睡觉时间远远长于听课时间,故不对文章的正确性

计算机网络学习(3)ARP协议

一.ARP 协议 网络层以上的协议用IP地址来标识网络接口,但以太数据帧传输时,以物理地址来标识网络接口.因此我们需要进行IP地址与物理地址之间的转化. 对于IPv4来说,我们使用ARP地址解析协议来完成IP地址与物理地址的转化(IPv6使用邻居发现协议进行IP地址与物理地址的转化,它包含在ICMPv6中). ARP协议提供了网络层地址(IP地址)到物理地址(mac地址)之间的动态映射.ARP协议 是地址解析的通用协议. 二.ARP缓存 ARP高速缓存(即ARP表)是 ARP地址解析协议能够高效

计算机网络基础:ARP协议 --- IP协议 --- ICMP + IGMP协议

ARP协议 ARP高速缓存:ARP把保存在高速缓存中的每一个映射地址项目都设置生存时间.凡超过生存时间的项目就从高速缓存中删除掉. ARP是解决同一局域网上的主机或路由器的IP地址和硬件地址的映射问题. IP协议 利用IP协议可以使这些性能各异的网络从用户看起来好像是一个统一的网络. ICMP协议 为了提高IP数据报交付成功的机会,在网际层用了网际控制报文协议ICMP. ICMP允许主机或路由器报告差错情况和提供有关异常情况的报告. ICMP报文格式 ICMP协议的应用 PING PING用来测

1 (计算机网络)我们常用的网络协议有哪些?

你先在浏览器里面输入 https://www.taobao,com,这是一个URL.浏览器只知道名字是"www.taobao.com",但是不知道具体的地点,所以不知道应该如何访问.于是,它打开地址簿去查找.可以使用一般的地址簿协议DNS去查找,还可以使用另一种更加精准的地址簿查找协议HTTPDNS. 无论用哪一种方法查找,最终都会得到这个地址:106.114.138.24.这个是IP地址,是互联网世界的"门牌号". 知道了目标地址,浏览器就开始打包它的请求.对于普

可靠数据传输的原理

TCP是运输层的协议,向上层(应用层)提供面向连接的可靠的服务.而TCP的下层是网络层,网络层提供的尽力而为的服务,也就是说不提供任何质量保证. 那么TCP是如何在不可信信道上为上层服务提供可靠的服务呢?这里的可靠包括两方面: 传输的数据比特不会受到损坏或丢失. 所有数据都是按照其发送顺序进行交付的. 一.可靠服务的模型 ? 如上图所示,运输层向应用层提供可靠数据传输服务. 运输层通过rdt_send()函数,调用数据传输协议,把数据交付给接收方的运输层.发送方的运输层调用udt_send()函

TCP协议,UDP协议,Utp,双绞线,DHCP协议,子网掩码,LAN,VLAN,网口,服务器,UI设计,Linux系统,Unix系统,名词解释

TCP协议: TCP:Transmission Control Protocol 传输控制协议TCP是一种面向连接(连接导向)的.可靠的.基于字节流的运输层(Transport layer)通信协议,由IETF的RFC 793说明(specified).在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,UDP是同一层内另一个重要的传输协议. UDP协议: UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Int

Http协议与TCP协议简单理解

在C#编写代码,很多时候会遇到Http协议或者TCP协议,这里做一个简单的理解. TCP协议对应于传输层,而HTTP协议对应于应用层,从本质上来说,二者没有可比性.Http协议是建立在TCP协议基础之上的,当浏览器需要从服务器获取网页数据的时候,会发出一次Http请求.Http会通过TCP建立起一个到服务器的连接通道,当本次请求需要的数据完毕后,Http会立即将TCP连接断开,这个过程是很短的.所以Http连接是一种短连接,是一种无状态的连接.所谓的无状态,是指浏览器每次向服务器发起请求的时候,

(转)DNS使用的是TCP协议还是UDP协议

转自:DNS使用的是TCP协议还是UDP协议 DNS同时占用UDP和TCP端口53是公认的,这种单个应用协议同时使用两种传输协议的情况在TCP/IP栈也算是个另类.但很少有人知道DNS分别在什么情况下使用这两种协议. 先简单介绍下TCP与UDP.     TCP是一种面向连接的协议,提供可靠的数据传输,一般服务质量要求比较高的情况,使用这个协议.UDP---用户数据报协议,是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务. TCP与UDP的区别:     UDP和TCP协议的主要区