首页 > 代码库 > 停止等待算法模拟

停止等待算法模拟

实现了两个程序通信的前提下,模拟实现停止等待ARQ协议。
模拟实现:
1.正常数据帧的通信过程
2.错误帧的通信过程

3.数据帧的丢失的通信过程

程序源码及资源下载 http://download.csdn.net/detail/qq_24054661/9802134

 

package com.stopandwait.test;

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) {
					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: ACK" + c);
						} else {
							jta.append("\r\nReceive: ACK" + c);
						}						
					}
					else if(i==Msg.length-1)
					{
						if (jta.getText() == null || "".equals(jta.getText())) {
							jta.append("数据传输成功!");
						} else {
							jta.append("\r\n"+"数据传输成功!");
							jta.setForeground(Color.BLUE);
							//jta.setEnabled(false);	
						}
						server.close();
					}
				}
				else if(c==-1)								//数据帧被丢弃(接收方不接收)
				{
					if (jta.getText() == null || "".equals(jta.getText())) {
						jta.append("Receive: ACK"+(i+1)+",重新发送"+(i+1)+"帧");
					} else {
						jta.append("\r\nReceive: ACK"+(i+1)+",重新发送"+(i+1)+"帧");
					}
					i=i-1;
				}
			}
			else											//超时,重传
			{
				if (jta.getText() == null || "".equals(jta.getText())) {
					jta.append("确认帧超时,重新发送"+(i+1)+"帧");
				} else {
					jta.append("\r\n确认帧超时,重新发送"+(i+1)+"帧");
				}
				i=i-1;	
			}	
		}
	}
}
package com.stopandwait.test;

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)+"号帧,发送ACK"+(i+2)+",内容为:"+c);
						} else {
							jta.append("\r\nReceive:" + "成功接收"+(i+1)+"号帧,发送ACK"+(i+2)+",内容为:"+c);
						}						
						dos.writeInt(i+2);
						Thread.sleep(100);
					}
					else
					{
						if (jta.getText() == null || "".equals(jta.getText())) {
							jta.append("Receive:" + "成功接收"+(i+1)+"号帧,发送ACK"+(i+2)+",内容为:"+c);
						} else {
							jta.append("\r\nReceive:" + "成功接收"+(i+1)+"号帧,发送ACK"+(i+2)+",内容为:"+c);
						}
						dos.writeInt(i+2);						//向发送方返回确认帧
						Thread.sleep(100);
					}
				}
				else											//数据帧内容错误
				{
					if (jta.getText() == null || "".equals(jta.getText())) {
						jta.append("Receive:" + "数据帧内容不符合顺序,丢弃,发送ACK"+(i+1)+"等待!");
					} else {
						jta.append("\r\nReceive:" + "数据帧内容不符合顺序,丢弃,发送ACK"+(i+1)+"等待!");
					}
					Thread.sleep(200);
					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:" + "数据帧错误,丢弃等待!");
				}			
				i=i-1;
				Thread.sleep(600);
				dos.writeInt(-2);
			}		
		}
		if (jta.getText() == null || "".equals(jta.getText())) {
			jta.append( "接收信息成功!");
		} else {
			jta.append("\r\n" + "接收信息成功!");
		}
		jta.setForeground(Color.RED);
		//jta.setEnabled(false);
		client.close();
	}
}

技术分享




停止等待算法模拟