//服务端
 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. start(共勉)

    “父母在,不远游,游必有方.”正犹豫着或者已经在路上的年轻人,如果选择远行,请风雨兼程,好好奋斗吧.

  2. Dockerfile注意事项

    准则 尽量将Dockerfile放在空目录中,如果目录中必须有其他文件,则使用.dockerignore文件. 避免安装不必须的包. 每个容器应该只关注一个功能点. 最小化镜像的层数. 多行参数时应该 ...

  3. .NET Core中妙用unsafe减少gc提升字符串处理性能

    一.前言 昨天在群里讨论怎么样效率的把一个字符串进行反转,一般的情况我们都知道,只要对String对象进行操作,那么就会生成新的String对象,比如"1"+"2&quo ...

  4. 归纳篇(一)CSS的position定位和float浮动

    近期会更新一系列博客,对基础知识再度做个巩固和梳理. 一.position定位 (一):position的属性 1.absolute:生成绝对定位的元素,相对于最近一级定位不是static的父元素来进 ...

  5. 如何在网上得到你想要的图片,如logo

    比如我们想得到网页:http://www.ahnu.edu.cn/里的安徽师范大学logo,可以这样做: 1.Ctrl+U,便进入了网页源代码页,也可以鼠标右键点"查看网页源代码" ...

  6. 多个超链接a 选中的和不选中的两种样式

    <script src="http://www.jq22.com/jquery/1.8.3/jquery.min.js"> 浏览器自带的jquery库 <scri ...

  7. 每天一个linux命令(41)--ping命令

    Linux系统的 ping 命令是常用的网络命令,它通常用来测试与目标主机的连通性,它通过发送 ICMP ECHO_REQUEST数据包到网络主机(send  ICMP  ECHO_REQUEST t ...

  8. phpcms中用到的几个重要的代码

    {pc:content action="lists" catid="12" moreinfo="1" order="id ASC& ...

  9. HTML复习

  10. spring mvc 结合 Hessian 配置

    spring mvc 结合 Hessian 配置 1.先在web.xml中配置 <!-- Hessian配置 --> <servlet> <servlet-name> ...