计算机网络——自顶向下方法,第三章编程作业,实现可靠传输协议,这里写了一个模拟停等协议的程序,没有写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;
}
}