利用udp模擬arq停止等待協(xié)議

停止等待arq協(xié)議:
停止等待協(xié)議(stop-and-wait)是最簡(jiǎn)單但也是最基礎(chǔ)的數(shù)據(jù)鏈路層協(xié)議。很多有關(guān)協(xié)議的基本概念都可以從這個(gè)協(xié)議中學(xué)習(xí)到?!巴V沟却本褪敲堪l(fā)送完一個(gè)分組就停止發(fā)送,等待對(duì)方的確認(rèn)。在收到確認(rèn)后再發(fā)送下一個(gè)分組。

由于這里我們采用的是端對(duì)端的傳輸,所以我們并沒(méi)有采用tcp進(jìn)行流式套接字的傳輸,而是采用udp,進(jìn)行的數(shù)據(jù)報(bào)的傳輸。

UDP 是User Datagram Protocol的簡(jiǎn)稱, 中文名是用戶數(shù)據(jù)報(bào)協(xié)議,是OSI(Open System Interconnection,開放式系統(tǒng)互聯(lián)) 參考模型中一種無(wú)連接的傳輸層協(xié)議,提供面向事務(wù)的簡(jiǎn)單不可靠信息傳送服務(wù),IETF RFC 768是UDP的正式規(guī)范。UDP在IP報(bào)文的協(xié)議號(hào)是17

UDP協(xié)議全稱是用戶數(shù)據(jù)報(bào)協(xié)議[1] ,在網(wǎng)絡(luò)中它與TCP協(xié)議一樣用于處理數(shù)據(jù)包,是一種無(wú)連接的協(xié)議。在OSI模型中,在第四層——傳輸層,處于IP協(xié)議的上一層。UDP有不提供數(shù)據(jù)包分組、組裝和不能對(duì)數(shù)據(jù)包進(jìn)行排序的缺點(diǎn),也就是說(shuō),當(dāng)報(bào)文發(fā)送之后,是無(wú)法得知其是否安全完整到達(dá)的。UDP用來(lái)支持那些需要在計(jì)算機(jī)之間傳輸數(shù)據(jù)的網(wǎng)絡(luò)應(yīng)用。包括網(wǎng)絡(luò)視頻會(huì)議系統(tǒng)在內(nèi)的眾多的客戶/服務(wù)器模式的網(wǎng)絡(luò)應(yīng)用都需要使用UDP協(xié)議。UDP協(xié)議從問(wèn)世至今已經(jīng)被使用了很多年,雖然其最初的光彩已經(jīng)被一些類似協(xié)議所掩蓋,但是即使是在今天UDP仍然不失為一項(xiàng)非常實(shí)用和可行的網(wǎng)絡(luò)傳輸層協(xié)議。

與所熟知的TCP(傳輸控制協(xié)議)協(xié)議一樣,UDP協(xié)議直接位于IP(網(wǎng)際協(xié)議)協(xié)議的頂層。根據(jù)OSI(開放系統(tǒng)互連)參考模型,UDP和TCP都屬于傳輸層協(xié)議。UDP協(xié)議的主要作用是將網(wǎng)絡(luò)數(shù)據(jù)流量壓縮成數(shù)據(jù)包的形式。一個(gè)典型的數(shù)據(jù)包就是一個(gè)二進(jìn)制數(shù)據(jù)的傳輸單位。每一個(gè)數(shù)據(jù)包的前8個(gè)字節(jié)用來(lái)包含報(bào)頭信息,剩余字節(jié)則用來(lái)包含具體的傳輸數(shù)據(jù)。

再解釋說(shuō)明一下,由于系統(tǒng)層面的原因,會(huì)有自動(dòng)校驗(yàn)的措施,而且因?yàn)槲易龅氖潜緳C(jī)的測(cè)試,出錯(cuò)率也會(huì)很低,所以我們需要模擬出錯(cuò)的情況。我們利用隨機(jī)數(shù)的算法,做了一個(gè)模擬的隨機(jī)數(shù)算法:



package UDP;

/**
 * Created by linSir on 16/10/5.用來(lái)模擬傳輸過(guò)程(udp)
 */
public class ImitateTransfer {

    /**
     * 用來(lái)模擬傳輸過(guò)程中的各種情況
     * 1.無(wú)差錯(cuò)情況(60%) 狀態(tài)碼:100
     * 2.出現(xiàn)差錯(cuò)
     * ①.接收到了,做校驗(yàn)時(shí)發(fā)現(xiàn)有錯(cuò)(20%) 狀態(tài)碼:101
     * ②.傳輸過(guò)程中丟失數(shù)據(jù)(20%) 狀態(tài)碼:102
     * 3.確認(rèn)丟失和確認(rèn)遲到
     * ①.確認(rèn)丟失(20%)狀態(tài)碼:103
     * ②.確認(rèn)遲到(20%)狀態(tài)碼:104
     */

    public static String transfer_send() {//發(fā)送數(shù)據(jù)的三種情況

        int x = (int) (Math.random() * 10);//0-9
        switch (x) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                return "100";
            case 6:
            case 7:
                return "101";
            case 8:
            case 9:
                return "102";
        }
        return "100";
    }


    public static String transfer_confirm() {//發(fā)送確認(rèn)命令的三種情況

        int x = (int) (Math.random() * 10);//0-9
        switch (x) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                return "100";
            case 6:
            case 7:
                return "103";
            case 8:
            case 9:
                return "104";
        }
        return "100";
    }
}



這樣我們就做完了,模擬出錯(cuò)的情況。下面我們看一下代碼,再解釋:

客戶端A(負(fù)責(zé)發(fā)送):



package UDP;


import 實(shí)驗(yàn)二.ImitateTransfer;

import java.text.SimpleDateFormat;
import java.util.*;
import java.io.IOException;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.*;
import javax.swing.border.BevelBorder;

import java.net.*;
import java.util.Timer;

class Window extends JFrame {
    private static JTextArea showArea;
    private JTextField inputField;
    private static String IPadress;
    public static String[] datas = new String[1000];
    public static Timer timer = new Timer();
    public static int m = 0;

    public static void sentData(String Message) {
        byte[] dataarr = new byte[100010];
        dataarr = Message.getBytes();

        try {
            Thread.currentThread().sleep(500);//毫秒
        } catch (Exception e) {
        }


        try {
            InetAddress sentIP = InetAddress.getByName(IPadress);
            DatagramSocket dsset = new DatagramSocket(62000);
            DatagramPacket dprec = new DatagramPacket(dataarr, dataarr.length, sentIP, 64650);
            System.out.println(sentIP);
            // 從己方62000 端口發(fā)送到客戶端64650端口
            dsset.send(dprec);
            dsset.close();
            timer1(1);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void recieveData() {
        byte[] dataarr = new byte[100010];
        try {
            DatagramSocket dsset = new DatagramSocket(63300);
            // 監(jiān)聽己方63300端口收到的消息
            DatagramPacket dprec = new DatagramPacket(dataarr, dataarr.length);
            dsset.receive(dprec);
            dsset.close();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            showArea.append(format.format(new Date()) + "\n" + "新消息: " + new String(dataarr).trim() + "\n");

            String content2 = new String(dataarr).trim().split("\\(")[1].split("\\)")[0];
            System.out.println(content2);
            switch (content2) {
                case "成功接受":
                    timer1(0);
                    m++;
                    String type = "";
                    type = ImitateTransfer.transfer_send();
                    switch (type) {
                        case "100":
                            type = "成功發(fā)送";
                            break;

                        case "101":
                            type = "做校驗(yàn)時(shí)出錯(cuò)";
                            break;

                        case "102":
                            type = "傳送時(shí)丟失";
                            break;
                    }
                    sentData("A發(fā)送:  數(shù)據(jù)為:" + datas[m] + "類型為:" + type + ";  (正常發(fā)送)");
                    showArea.append("A發(fā)送:  數(shù)據(jù)為:" + datas[m] + "類型為:" + type + ";  (正常發(fā)送)" + "\n");
                    break;

                case "確認(rèn)丟失":

                    break;


                case "確認(rèn)超時(shí)":

                    break;

            }


        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void startChat() {

        for (int i = 0; i < datas.length; i++) {
            datas[i] = String.valueOf(i);
        }

        JLabel displyjLabel = new JLabel("客戶端A");
        displyjLabel.setBounds(150, 10, 100, 15);
        JPanel myJPanel = new JPanel();
        myJPanel.setLayout(null);
        this.setContentPane(myJPanel);
        myJPanel.add(displyjLabel);
        showArea = new JTextArea();
        showArea.setLineWrap(true);
        JScrollPane scrollpane = new JScrollPane(showArea);
        scrollpane.setBounds(20, 30, 350, 350);
        scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED, Color.CYAN, Color.BLUE, null, null));
        scrollpane.setVisible(true);
        inputField = new JTextField();
        inputField.setBounds(20, 410, 280, 25);
        inputField.setVisible(true);
        myJPanel.add(scrollpane);
        JButton mybutton = new JButton("發(fā)送");
        mybutton.setBounds(310, 410, 60, 25);
        myJPanel.add(mybutton);
        myJPanel.add(inputField);
        myJPanel.setVisible(true);
        JButton quitjButton = new JButton("退出");
        quitjButton.setBounds(250, 450, 100, 30);
        myJPanel.add(quitjButton);
        quitjButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.exit(0);
            }
        });
        JButton returnjButton = new JButton("返回主界面");
        returnjButton.setBounds(20, 450, 100, 30);
        myJPanel.add(returnjButton);
        returnjButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                initWindow();
            }
        });
        this.setVisible(true);
        inputField.requestFocus();
        inputField.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                if (e.getKeyChar() == '\n') {

                    String type = "";
                    type = ImitateTransfer.transfer_send();
                    switch (type) {
                        case "100":
                            type = "成功發(fā)送";
                            break;

                        case "101":
                            type = "做校驗(yàn)時(shí)出錯(cuò)";
                            break;

                        case "102":
                            type = "傳送時(shí)丟失";
                            break;


                    }

                    //A發(fā)送:  數(shù)據(jù)為:1  類型為:成功發(fā)送;  (開始發(fā)送)
                    sentData("A發(fā)送:  數(shù)據(jù)為:" + datas[m] + "類型為:" + type + ";  (開始發(fā)送)");
                    inputField.setText("");
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    showArea.append("A發(fā)送:  數(shù)據(jù)為:" + datas[m] + "類型為:" + type + ";  (開始發(fā)送)" + "\n");
                    //sendMessage("A(發(fā)送)-" + datas[m] + "-" + 實(shí)驗(yàn)二.ImitateTransfer.transfer_send() + "---開始發(fā)送");
                }
            }
        });
        mybutton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                // 當(dāng)發(fā)送鍵被按下
                String type = "";
                type = ImitateTransfer.transfer_send();
                switch (type) {
                    case "100":
                        type = "成功發(fā)送";
                        break;

                    case "101":
                        type = "做校驗(yàn)時(shí)出錯(cuò)";
                        break;

                    case "102":
                        type = "傳送時(shí)丟失";
                        break;


                }

                //A發(fā)送:  數(shù)據(jù)為:1  類型為:成功發(fā)送;  (開始發(fā)送)
                sentData("A發(fā)送:  數(shù)據(jù)為:" + datas[m] + "類型為:" + type + ";  (開始發(fā)送)");
                inputField.setText("");
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                showArea.append("A發(fā)送:  數(shù)據(jù)為:" + datas[m] + "類型為:" + type + ";  (開始發(fā)送)" + "\n");
                //sendMessage("A(發(fā)送)-" + datas[m] + "-" + 實(shí)驗(yàn)二.ImitateTransfer.transfer_send() + "---開始發(fā)送");

            }
        });
    }

    public void initWindow() {
        JPanel myjPanel = new JPanel();
        myjPanel.setLayout(null);
        this.setContentPane(myjPanel);
        JLabel myjLabel = new JLabel("歡迎使用本聊天程序");
        myjLabel.setBounds(50, 100, 300, 40);
        myjLabel.setForeground(Color.cyan);
        myjLabel.setFont(new Font("HirakakuProN-W6", Font.BOLD, 30));
        JLabel tishiJLabel = new JLabel("請(qǐng)輸入對(duì)方的IP地址:");
        tishiJLabel.setBounds(15, 300, 150, 20);
        final JTextField ipJTextField = new JTextField("127.128.0.1");
        ipJTextField.setBounds(150, 300, 115, 20);
        JButton okJButton = new JButton("確定");
        okJButton.setBounds(280, 300, 70, 20);
        ipJTextField.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                if (e.getKeyChar() == '\n') {
                    startChat();
                }
            }
        });
        okJButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                IPadress = ipJTextField.getText();
                startChat();
            }
        });
        myjPanel.add(tishiJLabel);
        myjPanel.add(myjLabel);
        myjPanel.add(ipJTextField);
        myjPanel.add(okJButton);
        JButton quitjButton = new JButton("退出");
        quitjButton.setBounds(150, 350, 100, 30);
        myjPanel.add(quitjButton);
        quitjButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.exit(0);
            }
        });
        this.setVisible(true);

    }

    public Window() {
        this.setBounds(420, 100, 400, 550);
        this.setLayout(null);
        this.setTitle("客戶端A");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initWindow();
        while (true) {
            recieveData();
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Window();
    }

    public static void timer1(int q) {

        if (q == 1) {
            timer = new Timer();
            timer.schedule(new TimerTask() {
                public void run() {
                    String type = "";
                    type = ImitateTransfer.transfer_send();
                    switch (type) {
                        case "100":
                            type = "成功發(fā)送";
                            break;

                        case "101":
                            type = "做校驗(yàn)時(shí)出錯(cuò)";
                            break;

                        case "102":
                            type = "傳送時(shí)丟失";
                            break;
                    }
                    sentData("A發(fā)送:  數(shù)據(jù)為:" + datas[m] + "類型為:" + type + ";  (超時(shí)重發(fā))");
                    showArea.append("A發(fā)送:  數(shù)據(jù)為:" + datas[m] + "類型為:" + type + ";  (超時(shí)重發(fā))" + "\n");

                }
            }, 2000);
        }

        if (q == 0) {
            timer.cancel();
        }
    }


}




客戶端B(負(fù)責(zé)接收):



package UDP;


import java.text.SimpleDateFormat;
import java.util.*;
import java.io.IOException;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.*;
import javax.swing.border.BevelBorder;

import java.net.*;

class Window2 extends JFrame {
    private JTextArea showArea;
    private JTextField inputField;
    private String IPadress;

    public void sentData(String Message) {
        byte[] dataarr = new byte[100010];

        try {
            Thread.currentThread().sleep(500);//毫秒
        } catch (Exception e) {
        }


        dataarr = Message.getBytes();
        try {
            InetAddress sentIP = InetAddress.getByName(IPadress);
            DatagramSocket dsset = new DatagramSocket(60010);
            DatagramPacket dprec = new DatagramPacket(dataarr, dataarr.length, sentIP, 63300);
            // 從己方60010端口發(fā)送到對(duì)方63300端口
            dsset.send(dprec);
            dsset.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void recieveData() {
        byte[] dataarr = new byte[100010];
        try {
            DatagramSocket dsset = new DatagramSocket(64650);
            DatagramPacket dprec = new DatagramPacket(dataarr, dataarr.length);
            dsset.receive(dprec);
            dsset.close();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            showArea.append(format.format(new Date()) + "\n" + "新消息: " + new String(dataarr).trim() + "\n");

            String a_type = new String(dataarr).trim().split(":")[3].split(";")[0];
            String content = new String(dataarr).trim().split(":")[2].split("類")[0];
            //sentData("A發(fā)送:  數(shù)據(jù)為:" + datas[m] + "類型為:" + type + ";  (開始發(fā)送)");
            String type = "";
            type = ImitateTransfer.transfer_confirm();
            switch (type) {
                case "100":
                    type = "成功接受";
                    break;

                case "103":
                    type = "確認(rèn)丟失";
                    break;

                case "104":
                    type = "確認(rèn)超時(shí)";
                    break;
            }

            switch (a_type) {


                case "成功發(fā)送":
                    sentData("B發(fā)送:" + "收到的數(shù)據(jù)為:" + content + "   類型(" + type + ") ");
                    break;

                case "做校驗(yàn)時(shí)出錯(cuò)":
                    break;

                case "傳送時(shí)丟失":
                    break;


            }


        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void startChat() {
        JLabel displyjLabel = new JLabel("客戶端B");
        displyjLabel.setBounds(150, 10, 100, 15);
        JPanel myJPanel = new JPanel();
        myJPanel.setLayout(null);
        this.setContentPane(myJPanel);
        myJPanel.add(displyjLabel);
        showArea = new JTextArea();
        showArea.setLineWrap(true);
        JScrollPane scrollpane = new JScrollPane(showArea);
        scrollpane.setBounds(20, 30, 350, 350);
        scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED, Color.CYAN, Color.BLUE, null, null));
        scrollpane.setVisible(true);
        inputField = new JTextField();
        inputField.setBounds(20, 410, 280, 25);

        inputField.setVisible(true);
        myJPanel.add(scrollpane);
        JButton mybutton = new JButton("發(fā)送");
        mybutton.setBounds(310, 410, 60, 25);
        myJPanel.add(mybutton);
        myJPanel.add(inputField);
        myJPanel.setVisible(true);
        JButton quitjButton = new JButton("退出");
        quitjButton.setBounds(250, 450, 100, 30);
        myJPanel.add(quitjButton);
        quitjButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.exit(0);
            }
        });
        JButton returnjButton = new JButton("返回主界面");
        returnjButton.setBounds(20, 450, 100, 30);
        myJPanel.add(returnjButton);
        returnjButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                initWindow();
            }
        });
        this.setVisible(true);
        inputField.requestFocus();
        inputField.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                if (e.getKeyChar() == '\n') {
                    String Message = inputField.getText().trim();
                    sentData(Message);
                    inputField.setText("");
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    showArea.append(format.format(new Date()) + "\n" + "我發(fā)送: " + Message + "\n");
                }
            }
        });
        mybutton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                // 當(dāng)發(fā)送鍵被按下
                String Message = inputField.getText().trim();
                sentData(Message);
                inputField.setText("");
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                showArea.append(format.format(new Date()) + "\n" + "我發(fā)送: " + Message + "\n");

            }
        });
    }

    public void initWindow() {


        JPanel myjPanel = new JPanel();
        myjPanel.setLayout(null);
        this.setContentPane(myjPanel);
        JLabel myjLabel = new JLabel("歡迎使用本聊天程序");
        myjLabel.setBounds(50, 100, 300, 40);
        myjLabel.setForeground(Color.cyan);
        myjLabel.setFont(new Font("HirakakuProN-W6", Font.BOLD, 30));
        JLabel tishiJLabel = new JLabel("請(qǐng)輸入對(duì)方的IP地址:");
        tishiJLabel.setBounds(15, 300, 150, 20);
        final JTextField ipJTextField = new JTextField("127.128.0.1");
        ipJTextField.setBounds(150, 300, 115, 20);
        JButton okJButton = new JButton("確定");
        okJButton.setBounds(280, 300, 70, 20);
        ipJTextField.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                if (e.getKeyChar() == '\n') {
                    startChat();
                }
            }
        });
        okJButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                IPadress = ipJTextField.getText();
                startChat();
            }
        });
        myjPanel.add(tishiJLabel);
        myjPanel.add(myjLabel);
        myjPanel.add(ipJTextField);
        myjPanel.add(okJButton);
        JButton quitjButton = new JButton("退出");
        quitjButton.setBounds(150, 350, 100, 30);
        myjPanel.add(quitjButton);
        quitjButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                System.exit(0);
            }
        });
        this.setVisible(true);

    }

    public Window2() {
        this.setBounds(420, 100, 400, 550);
        this.setLayout(null);
        this.setTitle("客戶端B");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        initWindow();
        while (true) {
            recieveData();
            System.out.println("-----");
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new Window2();

    }

}


相信,有很多人,已經(jīng)看懂了,這個(gè)程序了,先聲明一下,本程序是我在上網(wǎng)找的,只是修改了一點(diǎn)點(diǎn)。

這個(gè)程序說(shuō)的就是,一個(gè)java的可視化界面+一個(gè)發(fā)送數(shù)據(jù)的函數(shù)+一個(gè)接收數(shù)據(jù)的函數(shù),無(wú)論發(fā)送還是接收,我都做了500毫秒的延遲,用來(lái)模擬在路上的時(shí)間,也都需要指定ip和端口號(hào),就可以從這個(gè)端口發(fā)送到對(duì)方的端口了,對(duì)方只需要監(jiān)視自己的端口就可以了。

然后,在發(fā)送數(shù)據(jù)的過(guò)程中,加了一個(gè)利用隨機(jī)數(shù)產(chǎn)生的。
發(fā)送的類型,有三種,分別是:1.成功數(shù)據(jù)發(fā)送 2.發(fā)送的數(shù)據(jù)做校驗(yàn)會(huì)出錯(cuò) 3.發(fā)送的數(shù)據(jù)超時(shí) 。
接收的類型也有三種,分別是:1.發(fā)送確認(rèn)成功 2.發(fā)送確認(rèn)超時(shí)
3.發(fā)送確認(rèn)丟失

當(dāng)A向B發(fā)送數(shù)據(jù)時(shí),B會(huì)判斷,如果是出錯(cuò)或者超時(shí),B不會(huì)做任何處理,這個(gè)時(shí)候便會(huì)觸發(fā)A的超時(shí)計(jì)時(shí)器,重傳。

當(dāng)B向A發(fā)送確認(rèn)時(shí),如果確認(rèn)超時(shí),或者確認(rèn)丟失,A都會(huì)重新向B發(fā)送正確的數(shù)據(jù)。

如果A接收到B的一次成功接收的指令,就會(huì)將數(shù)據(jù)向下滾動(dòng)一位,傳一下數(shù)據(jù)。

超時(shí)定時(shí)器(函數(shù)timer1)也很好理解,只是讓它兩秒的等待,然后去重新發(fā)送數(shù)據(jù),如果在兩秒內(nèi),收到了確認(rèn)了,成功接收的指令,就會(huì)關(guān)閉這個(gè)超時(shí)定時(shí)器。并且再向B發(fā)送一個(gè)數(shù)據(jù),同時(shí)再打開超時(shí)計(jì)時(shí)器就可以了。

當(dāng)然,操作也非常簡(jiǎn)單,只需要在,客戶端A的輸入窗口,敲一下回車,或者點(diǎn)擊一下發(fā)送就行,內(nèi)容是自動(dòng)填充的,不用手動(dòng)輸入。

效果圖:

效果圖1
效果圖2
效果圖3

大概這個(gè)模擬的過(guò)程就是這個(gè)樣子,當(dāng)然其中肯定有很多,代碼規(guī)范,代碼格式,代碼復(fù)用做的很不好的地方~ 歡迎大家提意見(jiàn),我都會(huì)改正的~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 個(gè)人認(rèn)為,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,215評(píng)論 0 8
  • 1.這篇文章不是本人原創(chuàng)的,只是個(gè)人為了對(duì)這部分知識(shí)做一個(gè)整理和系統(tǒng)的輸出而編輯成的,在此鄭重地向本文所引用文章的...
    SOMCENT閱讀 13,391評(píng)論 6 174
  • 本章討論TCP/IP體系中運(yùn)輸層最重要的兩種協(xié)議:UDP和TCP。必須弄清TCP的各種機(jī)制(如面向連接的可靠服務(wù)、...
    dmmy大印閱讀 1,076評(píng)論 0 0
  • 1 運(yùn)輸層協(xié)議概述 1.1 進(jìn)程之間的通信 網(wǎng)絡(luò)層是為主機(jī)之間提供邏輯通信,而運(yùn)輸層為應(yīng)用進(jìn)程之間提供端到端的邏輯...
    Mr希靈閱讀 8,331評(píng)論 0 34
  • 注:本文的圖片均來(lái)源于謝希仁《計(jì)算機(jī)網(wǎng)絡(luò)》第六版的課件PPT 1.重點(diǎn)內(nèi)容 (1)運(yùn)輸層為相互通信的應(yīng)用進(jìn)程提供邏...
    zuyuxia閱讀 1,221評(píng)論 0 1

友情鏈接更多精彩內(nèi)容