//服务端
 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. kali linux live(persistence)+PE+windows7安装多启动菜单优盘制作

    需要以下工具: 下载链接: 一.制作kali linux persistence 将32GU盘格式化为FAT32格式,使用win32diskimager将kalilinux镜像写入优盘,占用优盘3.4 ...

  2. BZOJ 3401: [Usaco2009 Mar]Look Up 仰望(离线+平衡树)

    刷银组刷得好开心= = 离线按权值排序,从大到小插入二叉树,查找树中比这个数大的 CODE: #include<cstdio>#include<iostream>#includ ...

  3. Tinyshell: 一个简易的shell命令解释器

    这是自己最近学习Linux系统编程之后写的一个练手的小程序,能很好地复习系统编程中的进程管理.信号.管道.文件等内容. 通过回顾写的过程中遇到的问题的形式记录程序的关键点,最后给出完整程序代码. 0. ...

  4. 支持向量机(SVM)理论总结系列.线性可分(附带R程序案例:用体重和心脏重量来预测一只猫的性别)

    附注:不要问我为什么写这么快,是16年写的. 1.名词解释 支持向量机中的机:在机器学习领域,常把一些算法看做一个机器,如分类机(也叫作分类器) 2.问题描述 空间中有很多已知类别的点,现在想用一个面 ...

  5. 规范 : angular ui router path & params

    在seo文章中提到url的path 必须是 why-us,而不是whyUS 所以定了规范,所有的path 必须why-us path ?后尾的是用来filter的,所以可以WhyUs 如果是不需要给s ...

  6. 【转载】JavaScript继承详解(二)

    这一章我们将会重点介绍JavaScript中几个重要的属性(this.constructor.prototype), 这些属性对于我们理解如何实现JavaScript中的类和继承起着至关重要的作用. ...

  7. java里Struts2学习登录练习详解

    最近在学struts2里面遇到很多错误,今天跟大家分享一下,我的开发工具是Eclipse: 1.到网上下载Struts2的包,这里不再累赘,百度有很多: 2.新建一个项目,记得后面加上web.xml文 ...

  8. 问题 : lang.NoClassDefFoundError: org/springframework/core/annotation/AnnotatedElementUtils,的解决方法

    今天在做junit 测试的时候  出现了一个问题,花了一段时间 才解决. java.lang.NoClassDefFoundError: org/springframework/core/annota ...

  9. 游戏UI框架设计(四) : 模态窗体管理

    游戏UI框架设计(四) --模态窗体管理 我们在开发UI窗体时,对于"弹出窗体"往往因为需要玩家优先处理弹出小窗体,则要求玩家不能(无法)点击"父窗体",这种窗 ...

  10. react 组件的生命周期

    组件的生命周期 过程 装载(Mounting) :组件被插入到 DOM 中: 更新(Updating) :组件重新渲染以更新 DOM: 卸载(Unmounting) :组件从 DOM 中移除. 过程 ...