计算机网络——自顶向下方法,第三章编程作业,实现可靠传输协议,这里写了一个模拟停等协议的程序,没有写GBN的。
分组丢失和ACK丢失都是通过随机数进行模拟的。
接收方程序:
import java.io.*; import java.net.*; public class Receiver extends Thread{ private boolean OutServer = false; private static ServerSocket server ; private static int ServerPort = 9878; public static void main(String[] args) { (new Receiver()).start(); } public Receiver() { try { server = new ServerSocket(ServerPort); } catch(java.io.IOException e) { System.out.println("Socket啟動有問題 !" ); System.out.println("IOException :" + e.toString()); } } public void run() { Socket socket ; ObjectInputStream in ; System.out.println("伺服器已啟動 !" ); while(!OutServer) { socket = null; try { synchronized(server) { socket = server.accept(); } //System.out.println("取得連線 : InetAddress = " + socket.getInetAddress()); socket.setSoTimeout(15000); in = new ObjectInputStream(socket.getInputStream()); Msg data = (Msg)in.readObject(); System.out.println("发送端正在发送的内容"+data.getN_msg()+" 状态:"+data.getInfo()); if(data.getInfo().equals("losePackage")) { System.out.println("分组丢失"); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeBytes("resend1"+'\n'); dos.close(); } else if(data.getInfo().equals("loseAck")) { System.out.println("ACK丢失"); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeBytes("resend2"+'\n'); dos.close(); } else { System.out.println("接收分组 "+data.getN_msg()+" 发送ACK "+data.getN_msg()); DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); dos.writeBytes("ok"+'\n'); dos.close(); } System.out.println(); in.close(); in = null ; socket.close(); } catch(java.io.IOException e) { System.out.println("Socket連線有問題111 !" ); System.out.println("IOException :" + e.toString()); } catch(java.lang.ClassNotFoundException e) { System.out.println("ClassNotFoundException :" + e.toString()); } } } }
发送端程序
import java.io.*; import java.net.*; public class Sender extends Thread{ private String address = "127.0.0.1"; private int port = 9878; public Sender() { Socket client = null ; for(int i=0;i<10; i++) { client = new Socket() ; Msg data = new Msg(i%2); InetSocketAddress isa = new InetSocketAddress(this.address,this.port); try { client.connect(isa,10000); ObjectOutputStream out = new ObjectOutputStream(client.getOutputStream()); out.writeObject(data); System.out.println("发送分组 "+data.getN_msg()); BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); String str = br.readLine(); if(str.equals("resend1")) { System.out.println("分组丢失,重发"); i--; out.flush(); out.close(); out = null ; data = null ; client.close(); client = null ; continue; } else if(str.equals("resend2")) { System.out.println("ACK丢失,重发"); i--; out.flush(); out.close(); out = null ; data = null ; client.close(); client = null ; continue; } else System.out.println("\n"+"接收ACK"+data.getN_msg()+" 发送分组"+(data.getN_msg()+1)%2); out.flush(); out.close(); out = null ; data = null ; client.close(); client = null ; } catch(java.io.IOException e) { System.out.println("Socket連線有問題 222!" ); System.out.println("IOException :" + e.toString()); } try { this.sleep(8000); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { new Sender(); } }
信息类Msg:
import java.io.Serializable; import java.util.*; public class Msg implements Serializable{ private int n_msg; private String info; private Random random; private int rdNum; public Msg(int n_msg) { this.n_msg = n_msg; MsgState(); } public void MsgState(){//用于模拟分组丢失,ACK丢失等情况 random = new Random(); rdNum = Math.abs(random.nextInt())%100; if (rdNum<20) info = "losePackage"; else if(rdNum>80) info ="loseAck"; else info ="noError"; } public int getN_msg() { return n_msg; } public void setN_msg(int n_msg) { this.n_msg = n_msg; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } }