//狀態抽象類
abstract class State
{
public abstract void Handle(Context context);
}
//狀態A
class ConcreteStateA : State
{
public override void Handle(Context context)
{
context.State = new ConcreteStateB();
}
}
//狀態B
class ConcreteStateB : State
{
public override void Handle(Context context)
{
context.State = new ConcreteStateA();
}
}
//上下文
class Context
{
private State state;
public Context(State state)
{
this.state = state;
}
public void Request()
{
state.Handle(this);
}
public State State { get => state; set => state = value; }
}
class Program
{
static void Main(string[] args)
{
Context c = new Context(new ConcreteStateA());
c.Request();
c.Request();
c.Request();
c.Request();
}
}
一個簡單的停等協議:
//分組
class Packet
{
private string data; //數據
private string checksum; //數據校驗和
private int num; //序號
public string Data { get => data; set => data = value; }
public string Checksum { get => checksum; set => checksum = value; }
public int Num { get => num; set => num = value; }
}
//狀態抽象類
abstract class State
{
public abstract void Change(Context context);
}
//終端抽象類
abstract class Context
{
private State state; //狀態
private string data; //數據
private string checksum; //校驗和
private Packet packet; //分組
private Context other; //對等方
//初始化狀態
public Context(State state)
{
this.state = state;
}
//運行
public void Run()
{
state.Change(this);
}
//rdt發送
public bool rdt_send(string data)
{
return true;
}
//rdt接收
public bool rdt_rcv(Packet packet)
{
return true;
}
//裝包
public Packet make_pkt(int num,string data,string checksum)
{
Console.WriteLine($"初始化分組[{num},{data},{checksum}]...");
Packet packet = new Packet();
packet.Num = num;
packet.Data = data;
packet.Checksum = checksum;
return packet;
}
//udt發送
public void udt_send(Packet packet)
{
Console.WriteLine("發送...");
//%50的出錯概率
if (Program.random.Next(0,100)<=50)
{
packet.Data = "error";
Console.WriteLine("出現bit差錯!");
}
Other.Packet = packet;
}
//解包
public void extract(Packet packet, out string data)
{
Console.WriteLine($"解析分組...");
data = packet.Data;
}
//上傳給高層
public void deliver_data(string data)
{
Console.WriteLine($"{data}");
}
//校驗和
public bool corrupt(Packet rcvpkt)
{
if(!rcvpkt.Data.Equals(rcvpkt.Checksum))
{
Console.WriteLine("分組出錯!");
return true;
}
else
{
return false;
}
}
public bool notcorrupt(Packet rcvpkt)
{
if (rcvpkt.Data.Equals(rcvpkt.Checksum))
{
return true;
}
else
{
return false;
}
}
//肯定確認
public bool isACK(Packet rcvpkt,int num)
{
if (rcvpkt.Data.Equals("ACK")&&rcvpkt.Num==num)
{
Console.WriteLine($"收到一個{num}號肯定確認!");
return true;
}
else
{
return false;
}
}
//是0號分組還是1號分組
public bool has_seq0(Packet packet)
{
if(packet.Num==0)
{
Console.WriteLine("收到了0號分組");
return true;
}else
{
return false;
}
}
public bool has_seq1(Packet packet)
{
if (packet.Num == 1)
{
Console.WriteLine("收到了1號分組");
return true;
}
else
{
return false;
}
}
public State State { get => state; set => state = value; }
public string Data { get => data; set => data = value; }
public Context Other { get => other; set => other = value; }
public Packet Packet { get => packet; set => packet = value; }
public string Checksum { get => checksum; set => checksum = value; }
}
//發送端
class Sender : Context
{
public Sender(State state) : base(state)
{
}
}
// 發送端狀態A
class SenderStateA : State
{
public override void Change(Context context)
{
Console.WriteLine("Sender:=>A");
Console.WriteLine("---------------------");
if (context.rdt_send(context.Data))
{
Packet packet = context.make_pkt(0,context.Data, context.Checksum);
context.udt_send(packet);
context.State = new SenderStateB();
//接收端處理
context.Other.Run();
}
}
}
// 發送端狀態B
class SenderStateB : State
{
public override void Change(Context context)
{
Console.WriteLine("Sender:=>B");
Console.WriteLine("---------------------");
Console.WriteLine("接收...");
if (context.rdt_rcv(context.Packet) && (context.corrupt(context.Packet) || context.isACK(context.Packet,1)))
{
Packet packet = context.make_pkt(0, context.Data, context.Checksum);
context.udt_send(packet);
context.Other.Run();
}else if (context.rdt_rcv(context.Packet)&& context.notcorrupt(context.Packet) && context.isACK(context.Packet,0))
{
context.State = new SenderStateC();
}
}
}
//發送端狀態C
class SenderStateC : State
{
public override void Change(Context context)
{
Console.WriteLine("Sender:=>C");
Console.WriteLine("---------------------");
if (context.rdt_send(context.Data))
{
Packet packet = context.make_pkt(1, context.Data, context.Checksum);
context.udt_send(packet);
context.State = new SenderStateD();
//接收端處理
context.Other.Run();
}
}
}
// 發送端狀態D
class SenderStateD : State
{
public override void Change(Context context)
{
Console.WriteLine("Sender:=>D");
Console.WriteLine("---------------------");
Console.WriteLine("接收...");
if (context.rdt_rcv(context.Packet) && (context.corrupt(context.Packet) || context.isACK(context.Packet,0)))
{
Packet packet = context.make_pkt(1, context.Data, context.Checksum);
context.udt_send(packet);
context.Other.Run();
}else if (context.rdt_rcv(context.Packet) && context.notcorrupt(context.Packet) && context.isACK(context.Packet,1))
{
context.State = new SenderStateA();
}
}
}
//接收端
class Receiver:Context
{
public Receiver(State state):base(state)
{
}
}
//接收端狀態A
class RcvStateA : State
{
public override void Change(Context context)
{
Console.WriteLine("Receiver:=>A");
Console.WriteLine("------------------------");
Console.WriteLine("接收...");
if (context.rdt_rcv(context.Packet) && (context.corrupt(context.Packet) || context.has_seq1(context.Packet)))
{
Packet packet = context.make_pkt(1,"ACK", "ACK");
context.udt_send(packet);
context.Other.Run();
}
else if(context.rdt_rcv(context.Packet) && context.notcorrupt(context.Packet) && context.has_seq0(context.Packet))
{
string data = "";
context.extract(context.Packet,out data);
context.deliver_data(data);
Packet packet = context.make_pkt(0,"ACK","ACK");
context.udt_send(packet);
context.State = new RcvStateB();
context.Other.Run();
}
}
}
// 接收端狀態B
class RcvStateB : State
{
public override void Change(Context context)
{
Console.WriteLine("Receiver:=>B");
Console.WriteLine("------------------------");
Console.WriteLine("接收...");
if (context.rdt_rcv(context.Packet) && (context.corrupt(context.Packet) || context.has_seq0(context.Packet)))
{
Packet packet = context.make_pkt(0,"ACK", "ACK");
context.udt_send(packet);
context.Other.Run();
}
else if (context.rdt_rcv(context.Packet) && context.notcorrupt(context.Packet) && context.has_seq1(context.Packet))
{
string data = "";
context.extract(context.Packet, out data);
context.deliver_data(data);
Packet packet = context.make_pkt(1,"ACK", "ACK");
context.udt_send(packet);
context.State = new RcvStateA();
context.Other.Run();
}
}
}
class Program
{
//產生隨機數用於模仿出錯概率
public static readonly Random random = new Random();
static void Main(string[] args)
{
Sender sender = new Sender(new SenderStateA());
Receiver receiver = new Receiver(new RcvStateA());
//建立連接
sender.Other = receiver;
receiver.Other = sender;
sender.Data = "hello ";
sender.Checksum = "hello ";
sender.Run();
sender.Data = "world!";
sender.Checksum = "world!";
sender.Run();
Console.WriteLine("-----------SUCCESS-----------");
}
}