⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbnunit.pas

📁 网络试验程序
💻 PAS
字号:
unit GBNUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ScktComp, ExtCtrls;

type
  TClientForm1 = class(TForm)
    Button2: TButton;
    Edit1: TEdit;
    Timer1: TTimer;
    ATimer: TTimer;
    ResendTimer: TTimer;
    Memo2: TMemo;
    Memo1: TMemo;
    AtoBerr: TCheckBox;
    BtoAerr: TCheckBox;
    Button1: TButton;
    A: TClientSocket;
    B: TClientSocket;
    Server: TServerSocket;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    Button3: TButton;
    Panel1: TPanel;
    GroupBox3: TGroupBox;
    Label1: TLabel;
    Label3: TLabel;
    Image1: TImage;
    Panel2: TPanel;
    GroupBox4: TGroupBox;
    procedure FormCreate(Sender: TObject);
    procedure BRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure ARead(Sender: TObject; Socket: TCustomWinSocket);
    procedure Button2Click(Sender: TObject);
    procedure ServerClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure Timer1Timer(Sender: TObject);
    procedure Send(i: Integer);
    procedure StartTimer();
    procedure StopTimer();
    procedure ATimerTimer(Sender: TObject);
    function GetLastStr(Str: String; num: Integer): String;
    function GetFirStr(Str: String; num: Integer): String;
    procedure ResendTimerTimer(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  N=5;

var
  ClientForm1: TClientForm1;
  APort, BPort: Integer;  //记录是哪一个ClientSocket的RemotePort
  rcvMsg: String;  //记录Server收到的Message
  Data: String;  //记录发送端A要发送的数据
  NextSeqNum, Base, ExpectedSeqNum, SentNum, ResendBase: Integer;
  returnMsg: String; //接收端B要发回的ACD内容
  toAMsg: String;  //发送端A最后收到的数据
  LastSent: Integer;  //发送端A最后发出的数据包序号

implementation

{$R *.dfm}
{$R 1.RES}

procedure TClientForm1.FormCreate(Sender: TObject);
begin
  Server.Active := true;
  A.Active := true;
  B.Active := true;
  Memo1.Text := '';
  Memo2.Text := '';

  Base := 0;
  NextSeqNum := 0;
  ExpectedSeqNum := 0;
  SentNum := 0;
end;

procedure TClientForm1.Send(i: Integer);
begin
  Edit1.SetFocus;
  Edit1.SelStart := SentNum * 10 + i;
  Edit1.SelLength := 1;
  LastSent := i;
  A.Socket.SendText(IntToStr(i)+':  ' + Edit1.SelText);
end;

procedure TClientForm1.BRead(Sender: TObject; Socket: TCustomWinSocket);
begin
  toAMsg := Socket.ReceiveText;
  if (GetFirStr(toAMsg, 3) = 'ACK') then
     begin
       if (StrToInt(GetLastStr(toAMsg, 1)) = 9) then SentNum := SentNum + 1;
       Base := StrToInt(GetLastStr(toAMsg, 1)) + 1;
       ATimer.Enabled := false;
       //SentNum := SentNum + 1;
       if (Base = NextSeqNum) then
          StopTimer
       else
          StartTimer;
     end;
end;

procedure TClientForm1.ARead(Sender: TObject; Socket: TCustomWinSocket);
var
  tmp: String;
begin
  tmp := Socket.ReceiveText;
  if (ExpectedSeqNum = StrToInt(GetFirStr(tmp, 1))) and (Length(tmp) > 1) then
     begin
       Memo2.Lines.Add(tmp);
       returnMsg := 'ACK _________' + IntToStr(ExpectedSeqNum);
       B.Socket.SendText(returnMsg);
       ExpectedSeqNum := ExpectedSeqNum + 1;
       if ExpectedSeqNum > 9 then ExpectedSeqNum := 0;
     end
  else
     begin
       B.Socket.SendText(returnMsg);
     end;

end;

procedure TClientForm1.Button2Click(Sender: TObject);
begin
  //B.Socket.SendText(Edit1.Text);
  Data := Edit1.Text;
  //Edit1.Text := '';
  Timer1.Enabled := true;
  Button2.Enabled := false;
end;

procedure TClientForm1.ServerClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
var
  tmp: integer;
begin
  BPort := Socket.RemotePort;
  APort := Socket.RemotePort;
  if (APort < BPort) then
     begin
       tmp := APort;
       APort := BPort;
       BPort := tmp;
     end;
end;

procedure TClientForm1.ServerClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  rcvMsg := Socket.ReceiveText;
  if (Socket.RemotePort = APort) then
     if BtoAerr.Checked then
        begin
          //如果A到B出错,则“网络”什么都不干
        end
     else
        begin
          Memo1.Lines.Add('B-->A: ' + rcvMsg);
          Server.Socket.Connections[1].SendText(rcvMsg);
        end
  else
     if AtoBerr.Checked then
        begin
          //如果B到A出错,则“网络”什么都不干
        end
     else
        begin
          Memo1.Lines.Add('A-->B: ' + rcvMsg);
          Server.Socket.Connections[0].SendText(rcvMsg);
        end
end;

procedure TClientForm1.Timer1Timer(Sender: TObject);
begin
  if (NextSeqNum < Base + N) then
     begin
       Send(NextSeqNum);
       if (Base = NextSeqNum) then StartTimer;
       NextSeqNum := NextSeqNum + 1;
       if NextSeqNum > 9 then NextSeqNum := 0;
     end
  else
     begin
     end;
  if (Edit1.SelStart >= Length(Edit1.Text)-1) and (StrToInt(GetLastStr(toAMsg, 1)) = LastSent - 1) then Timer1.Enabled := false;

end;

procedure TClientForm1.StartTimer();
begin
  ATimer.Enabled := true;
end;

procedure TClientForm1.StopTimer();
begin
  ATimer.Enabled := false;
end;

function TClientForm1.GetLastStr(Str: String; num: Integer): String;
var
  tmpArr: Array[0..1000] of char;
  tmpStr: String;
  i: Integer;
begin
  StrPCopy(tmpArr, Str);
  tmpStr := '';
  for i := Length(Str) - num to Length(Str) do
    tmpStr := tmpStr + tmpArr[i];
  Result := tmpStr;
end;

function TClientForm1.GetFirStr(Str: String; num: Integer): String;
var
  tmpArr: Array[0..1000] of char;
  tmpStr: String;
  i: Integer;
begin
  StrPCopy(tmpArr, Str);
  for i := 0 to num - 1 do
    tmpStr := tmpStr + tmpArr[i];
  Result := tmpStr;
end;


procedure TClientForm1.ATimerTimer(Sender: TObject);
begin
  StartTimer;
  ResendBase := Base;
  NextSeqNum := Base;
  ResendTimer.Enabled := true;
end;

procedure TClientForm1.ResendTimerTimer(Sender: TObject);
begin
  if (ResendBase <= NextSeqNum - 1) then
     begin
       Send(ResendBase);
       ResendBase := ResendBase + 1;
     end
  else
     begin
       ResendTimer.Enabled := false;
     end;
end;

procedure TClientForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text := '';
  AtoBerr.Checked := false;
  BtoAerr.Checked := false;
  Button2.Enabled := true;
  Timer1.Enabled := false;
  ResendTimer.Enabled := false;
  A.Active := false;
  B.Active := false;
  Server.Active := false;
  Server.Active := true;
  A.Active := true;
  B.Active := true;
  Memo1.Text := '';
  Memo2.Text := '';
  Base := 0;
  NextSeqNum := 0;
  ExpectedSeqNum := 0;
  SentNum := 0;
  Edit1.SetFocus;
end;

procedure TClientForm1.Button3Click(Sender: TObject);
begin
    ClientForm1.Close ;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -