//服务端 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; import java.net.*; import java.security.Timestamp; import java.util.*; import java.util.prefs.BackingStoreException; import javax.swing.*; public class IServer extends JFrame { private static long time1; private static long time2; private JPanel jp = new JPanel(); private JTextArea jta = new JTextArea(); private JScrollPane jsp = null; private JButton jb = new JButton("发送"); private JTextField jtf = new JTextField(30); private ServerSocket server; private Socket socket; DataOutputStream dos; DataInputStream dis; public IServer() throws IOException { Toolkit t = Toolkit.getDefaultToolkit(); Dimension Size =t.getScreenSize(); int width = Size.width; int height = Size.height; setLocationByPlatform(true); jsp = new JScrollPane(jta); this.setTitle("发送方"); this.setSize(600, 500); this.setBounds((width - 600) / 2, (height - 500) / 2, 600,500); jp.add(jtf); jp.add(jb); this.add(jsp, BorderLayout.CENTER); this.add(jp, BorderLayout.SOUTH); jta.setCaretPosition(jta.getDocument().getLength());// 设置滚动条自动滚动 this.setVisible(true); this.setAlwaysOnTop(true); server = new ServerSocket(9000); socket= server.accept(); this.setDefaultCloseOperation(EXIT_ON_CLOSE); dos = new DataOutputStream(socket.getOutputStream()); dis =new DataInputStream(socket.getInputStream()); jb.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ try { Send(); } catch (InterruptedException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } public static void main(String[] args) throws IOException, InterruptedException { new IServer(); } public void Send() throws InterruptedException, IOException { String info = jtf.getText(); jtf.setText(""); char[] Msg = info.toCharArray(); dos.write(Msg.length); for(int i=0;i<Msg.length;i++) { Random random=new java.util.Random(); //实现数据帧错传,以随机数的概率来实现 int result=random.nextInt(21); if(result>=4) { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Sending...:" + Msg[i]); } else { jta.append("\r\nSending...:" + Msg[i]); } dos.writeChar(Msg[i]); //发送数据帧 time1 = System.currentTimeMillis(); //设置超时计时器 } else { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Sending...:" + Msg[i]); } else { jta.append("\r\nSending...:" + Msg[i]); } dos.writeChar('η'); //发送数据帧 time1 = System.currentTimeMillis(); //设置超时计时器 } int c = dis.readInt(); //接受客户端确认帧 time2 = System.currentTimeMillis(); long time = time2-time1; //System.out.println("接收所用时间:"+time); if(time<500) //确认帧未超时 { if(c==i+2) //确认帧正确,传输成功,准备传输下一个帧 { if(i<Msg.length-1) { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Receive:" + c); } else { jta.append("\r\nReceive:" + c); } //System.out.println("接收方返回帧:"+c+" 第"+(i+1)+"号帧传输成功!"); } else { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Receive:" + (i+2)+"数据传输成功!"); } else { jta.append("\r\nReceive:" + (i+2)+"数据传输成功!"); jta.setEnabled(false); } //System.out.println("第"+(i+1)+"号帧传输成功!"); //System.out.println("数据传输成功!"); server.close(); } } else if(c==-2) //确认帧出错,超时重传 { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Receive:数据帧出错,丢弃等待....."+ "确认帧接收超时,重新发送"+(i+1)+"帧"); } else { jta.append("\r\nReceive:Receive:数据帧出错,丢弃等待....." +"确认帧接收超时,重新发送"+(i+1)+"帧"); } //System.out.println("数据帧出错,丢弃等待....."); Thread.sleep(300); //System.out.println("确认帧接收超时,重新发送"+(i+1)+"帧"); i=i-1; } } else//超时,重传 { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Receive:" +"确认帧接收超时,重新发送"+(i+1)+"帧"); } else { jta.append("\r\nReceive:" + "确认帧接收超时,重新发送"+(i+1)+"帧"); } //System.out.println("确认帧接收超时,重新发送"+(i+1)+"帧"); i=i-1; } } } }
//客户端
//客户端 import java.awt.*; import java.io.*; import java.net.*; import java.util.*; import javax.swing.*; public class IClient extends JFrame { JPanel jp = new JPanel(); JTextArea jta = new JTextArea(); JScrollPane jsp = null; public IClient() { Toolkit t = Toolkit.getDefaultToolkit(); Dimension Size =t.getScreenSize(); int width = Size.width; int height = Size.height; setLocationByPlatform(true); this.setAlwaysOnTop(true); jsp = new JScrollPane(jta); this.setTitle("接收方"); this.add(jp); this.setSize(500, 400); this.setBounds((width - 500) / 2, (height - 400) / 2, 600,500); this.add(jsp, BorderLayout.CENTER); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException { new IClient().Receive(); } public void Receive() throws UnknownHostException, IOException, InterruptedException { Socket client = new Socket("localhost",9000); DataOutputStream dos = new DataOutputStream(client.getOutputStream()); DataInputStream dis =new DataInputStream(client.getInputStream()); int length = dis.read(); //读取接收数据帧的长度 //System.out.println(length); //输出要接受的数据的长度 for(int i=0;i<length;i++) { char c = dis.readChar(); //接收数据帧,判断是否正确 if(c!='η'){ //CRC数据帧校验正确 Random ran=new java.util.Random(); int re=ran.nextInt(13); if(re>=4){ //数据帧帧数正确 if(i<length-1) { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Receive:" + "成功接收"+(i+1)+"号帧,内容为:"+c); } else { jta.append("\r\nReceive:" + "成功接收"+(i+1)+"号帧,内容为:"+c); } //System.out.println("成功接收"+(i+1)+"号帧,内容为:"+c); //输出接受到的数据帧 dos.writeInt(i+2); } else { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Receive:" + "成功接收"+(i+1)+"号帧,内容为:"+c); } else { jta.append("\r\nReceive:" + "成功接收"+(i+1)+"号帧,内容为:"+c); } //System.out.println("成功接收"+(i+1)+"号帧,内容为:"+c); dos.writeInt(i+2); //向发送方返回确认帧 Thread.sleep(100); } } else //数据帧内容错误 { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Receive:" + "不是所需要的帧,丢弃等待!"); } else { jta.append("\r\nReceive:" + "不是所需要的帧,丢弃等待!"); } Thread.sleep(600); //System.out.println("不是所需要的帧,丢弃等待!"); dos.writeInt(-1); i=i-1; } } else if(c=='η') //CRC数据帧错误丢弃等待 { if (jta.getText() == null || "".equals(jta.getText())) { jta.append("Receive:" + "数据帧错误!"); } else { jta.append("\r\nReceive:" + "数据帧错误!"); } //System.out.println("数据帧错误!"); i=i-1; dos.writeInt(-2); } } if (jta.getText() == null || "".equals(jta.getText())) { jta.append( "接收信息成功!"); } else { jta.append("\r\n" + "接收信息成功!"); } jta.setEnabled(false); //System.out.println("接收信息成功!"); client.close(); } }
停止等待ARQ算法模拟
一、目的:
在两个程序通信的前提下,模拟实现停止等待ARQ协议。
要求模拟实现:
1. 正常数据帧的通信过程
2. 错误帧的通信过程
3. 数据帧的丢失的通信过程
二、实验内容与步骤
按照如下算法进行实现:
发方程序:
(1) 从主机取一个数据帧,送交发送缓存。
(2) V(S)←0。
(3) N(S)←V(S)。
(4) 将发送缓存中的数据帧发送出去。
(5) 设置超时计时器。
(6) 等待。
(7) 收到确认帧 ACKn,
若 n = 1 – V(s),则:
从主机取一个新的数据帧,放入发送缓存;
V(S)←[1 - V(S)],转到 (3)。
否则,丢弃这个确认帧,转到(6)。
(8) 若超时计时器时间到,则转到(4)。
收方:
(1) V(R)←0。
(2) 等待。
(3) 收到一个数据帧;
若 CRC校验无误
若 N(S) = V(R),则执行(4);
否则丢弃此数据帧,然后转到(6)。
否则丢弃此数据帧,然后转到(2)。
(4) 将收到的数据帧中的数据部分送交上层软件
(5) V(R)←[1 - V(R)]。
(6) n←V(R);
发送确认帧 ACKn,转到(2)。
socket模拟通信实现ARQ停止等待协议的更多相关文章
-
TCP协议总结--停止等待协议,连续ARQ协议,滑动窗口协议
前言:在学习tcp三次握手的过程之中,由于一直无法解释tcpdump命令抓的包中seq和ack的含义,就将tcp协议往深入的了解了一下,了解到了几个协议,做一个小结. 先来看看我的问题: 这是用tcp ...
-
计算机网络之流量控制(停止-等待协议、滑动窗口、后退N帧协议GBN、选择重传协议SR)、滑动窗口、可靠传输机制
文章转自:https://blog.csdn.net/weixin_43914604/article/details/104908762 学习课程:<2019王道考研计算机网络> 学习目的 ...
-
[knowledge] 停止等待协议
再读TCP/IP详解 说到流量控制, 可能便涉及了两方面 1. 停止等待协议. https://baike.baidu.com/item/%E5%81%9C%E6%AD%A2%E7%AD%89%E5% ...
-
C#高性能大容量SOCKET并发(七):协议字符集
原文:C#高性能大容量SOCKET并发(七):协议字符集 UTF-8 UTF-8是UNICODE的一种变长字符编码又称万国码,由Ken Thompson于1992年创建.现在已经标准化为RFC 362 ...
-
网络编程----------SOCKET编程实现简单的TCP协议
首先我们须要大致了解TCP的几点知识: 1.TCP的特点:面向连接的可靠性传输 2.TCP的三次握手建立连接和四次挥手释放连接.但为什么TCP要三次握手建立连接呢? 答:由于两次握手无法保证可靠性.若 ...
-
Python网络编程(socket模块、缓冲区、http协议)
网络的概念:主机 端口 IP 协议 服务器: localhost/127.0.0.1 客户端: 只是在本机启动客户端,用127.0.0.1访问 服务器: 0.0.0.0 客户端: ...
-
Day09: socket网络编程-OSI七层协议,tcp/udp套接字,tcp粘包问题,socketserver
今日内容:socket网络编程 1.OSI七层协议 2.基于tcp协议的套接字通信 3.模拟ssh远程执行命令 4.tcp的粘包问题及解决方案 5.基于udp协议的套接字 ...
-
socket套接字编程 HTTP协议
socket套接字编程 套接字介绍 1. 套接字 : 实现网络编程进行数据传输的一种技术手段 2. Python实现套接字编程:import socket 3. 套接字分类 >流式套接 ...
-
java基础知识回顾之java Socket学习(二)--TCP协议编程
TCP传输(传输控制协议):TCP协议是一种面向连接的,可靠的字节流服务.当客户端和服务器端彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能进行数据的传输.它将一台主机发出的字节流无差错的 ...
随机推荐
-
IE6中使用通用选择器模拟子选择器效果
IE6及更低版本不支持高级选择器:IE7有个bug,对于子选择器和相邻同胞选择器,如果父元素和子元素有HTML注释,会出问题. 下面我们使用通用选择器来模拟子选择器的效果. 原理:首先在所有后代上应用 ...
-
Sunglasses
It's hot this summer. It also reminds me of one case about sunglasses. She was new to this company a ...
-
内容输出Linux文件系统的的实现:创建一个文件的过程
题记:写这篇博客要主是加深自己对内容输出的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢. 考虑上面这个命令: who > userlist 当这个命令完成后,文件系统增加l一 ...
-
Thrift反序列化导致OOM(转)
概述 最近线上的日志处理服务偶尔会出现Out Of Memory的问题,从Exception的call stack中顺藤摸瓜,最终定位到是thrift反序列化的问题. 发现问题 先交代一下问题现场: ...
-
Java学习笔记26(Math类、Arrays类、BigInteger类、BigDecimal类)
Math类:数学工具类,做一些数学计算,开方,对数,三角函数等 所有方法都是静态方法,不需要建立对象,直接用类名调用即可 示例: 这里写几个在日常开发中会用到的,比如三角函数之类的平时不会用到,了解即 ...
-
vxWorks内核实现基本原理
内核实现基本原理 VxWorks 内核维护三个队列:tick队列.ready 队列.active 队列.另外还有一个队列涉及任务,即任务等待资源时所处的队列,这个队列可以是VxWorks内核提 ...
-
Android Studio apk打包,keystore.jks文件生成,根据keystore密钥获取SHA1安全码
keystore.jks文件生成,打包APK 选择Build > Generate Signed APK 出现如下弹框: 然后点击Create new...(创建的意思)出现另一个弹框,在做如下 ...
-
Programming Contest Ranking(题解)
Programming Contest Ranking . 题目描述 Heilongjiang Programming Contest will end successfully! And your ...
-
ruby安装及webStorm配置SCSS
sass安装: 步骤:(window系统) 1.下载RubyInstaller(v2.4.3),运行安装,基本直接next安装,不过有个add to PATH的选项一定要勾选,这样就不用配置环境变量. ...
-
MySQL配置主主及主从备份
原文:https://www.cnblogs.com/ahaii/p/6307648.html MySQL主从备份配置实例 场景: 1.主服务器192.168.0.225.从服务器192.168.0. ...