//服务端
 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停止等待协议的更多相关文章

  1. TCP协议总结--停止等待协议,连续ARQ协议,滑动窗口协议

    前言:在学习tcp三次握手的过程之中,由于一直无法解释tcpdump命令抓的包中seq和ack的含义,就将tcp协议往深入的了解了一下,了解到了几个协议,做一个小结. 先来看看我的问题: 这是用tcp ...

  2. 计算机网络之流量控制(停止-等待协议、滑动窗口、后退N帧协议GBN、选择重传协议SR)、滑动窗口、可靠传输机制

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/104908762 学习课程:<2019王道考研计算机网络> 学习目的 ...

  3. [knowledge] 停止等待协议

    再读TCP/IP详解 说到流量控制, 可能便涉及了两方面 1. 停止等待协议. https://baike.baidu.com/item/%E5%81%9C%E6%AD%A2%E7%AD%89%E5% ...

  4. C#高性能大容量SOCKET并发(七):协议字符集

    原文:C#高性能大容量SOCKET并发(七):协议字符集 UTF-8 UTF-8是UNICODE的一种变长字符编码又称万国码,由Ken Thompson于1992年创建.现在已经标准化为RFC 362 ...

  5. 网络编程----------SOCKET编程实现简单的TCP协议

    首先我们须要大致了解TCP的几点知识: 1.TCP的特点:面向连接的可靠性传输 2.TCP的三次握手建立连接和四次挥手释放连接.但为什么TCP要三次握手建立连接呢? 答:由于两次握手无法保证可靠性.若 ...

  6. Python网络编程(socket模块、缓冲区、http协议)

      网络的概念:主机   端口  IP  协议 服务器: localhost/127.0.0.1 客户端: 只是在本机启动客户端,用127.0.0.1访问     服务器: 0.0.0.0 客户端: ...

  7. Day09: socket网络编程-OSI七层协议,tcp/udp套接字,tcp粘包问题,socketserver

    今日内容:socket网络编程    1.OSI七层协议    2.基于tcp协议的套接字通信    3.模拟ssh远程执行命令    4.tcp的粘包问题及解决方案    5.基于udp协议的套接字 ...

  8. socket套接字编程 HTTP协议

    socket套接字编程  套接字介绍  1. 套接字 : 实现网络编程进行数据传输的一种技术手段  2. Python实现套接字编程:import  socket  3. 套接字分类 >流式套接 ...

  9. java基础知识回顾之java Socket学习(二)--TCP协议编程

    TCP传输(传输控制协议):TCP协议是一种面向连接的,可靠的字节流服务.当客户端和服务器端彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能进行数据的传输.它将一台主机发出的字节流无差错的 ...

随机推荐

  1. Mysql条件的类型决定了是否能走索引

    sku表总数据量将近7百万 SELECT count(1) from sku;

  2. slf4j+log4j的使用

    maven依赖引入 <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j1 ...

  3. 【安装eclipse, 配置java环境教程】 编写第一个java程序

    写java通常用eclipse编写,还有一款编辑器比较流行叫IJ.这里我们只说下eclipse编写java的前期工作. 在安装eclipse之前要下载java的sdk文件,即java SE:否则无法运 ...

  4. Spring源码解析一:IOC容器设计

    一.IOC接口设计 IOC容器设计的源码主要在spring-beans.jar.spring-context.jar这两个包中.IOC容器主要接口设计如下: 这里的接口设计有两条主线:BeanFact ...

  5. 轻松理解python中的闭包和装饰器 (下)

    在 上篇 我们讲了python将函数做为返回值和闭包的概念,下面我们继续讲解函数做参数和装饰器,这个功能相当方便实用,可以极大地简化代码,就让我们go on吧! 能接受函数做参数的函数我们称之为高阶函 ...

  6. ZOJ 1492 Maximum Clique 搜索最大团

    ZOJ1492 题意:给一个无向图 求最大团的大小.节点数小于50 数据有限,考虑记忆化搜索,方程很好给出. 令 Si={vi,vi+1.....vn} mc[i]表示Si最大团的大小,倒着推算. 必 ...

  7. 第34篇 再谈http协议

    从打开一个网址说起 当在浏览器中输入一个网址的时候,浏览器会渲染出对应的网页的内容.作为web开发人员来说,应该知道这个过程: 当输入的一个网址为域名的时候,浏览器则根据本机的网关和DNS服务器来解析 ...

  8. Dapper的扩展这个你知道嘛?

    之前写的ORM对比文章中,我选Dapper作为底层ADO的基础访问框架后,我对此再次进行进一步的深入研究,发现里面还有延伸了一些好用的扩展方法和特性,那我便简单的跟大家说一下特性标签. 一.Table ...

  9. MyBatis 源码分析——类型处理器

    官网上面讲到:无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型.那 ...

  10. 第35篇 IIS执行原理

    服务器的监听(IIS6.0+版本) 当请求到达服务器时,请求最终会到达TCPIP.SYS驱动程序,TCPIP.SYS将请求转发给HTTP.SYS网络驱动程序的请求队列中(可以理解为专门处理http请求 ...