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

📄 rule104.pas

📁 104规约服务端测试程序
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  if i < 0 then
    Exit;
  CloseLink(Socket, i);
  MessageList.Add(Socket.RemoteAddress + ': 断开连接');
end;

procedure TSocket104.OnClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
var
  i: Integer;
begin
  i:= IndexOf(Socket.RemoteAddress);
  if i < 0 then
    Exit;
  CloseLink(Socket, i);
  ErrorCode := 0;
  MessageList.Add(Socket.RemoteAddress + ': 出错,断开连接');
end;

procedure TSocket104.OnClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  i, j, len: Integer;
  buf: array of Byte;
  pcl: PClientLink;
  ftype, APDU: Byte;
begin
  len:=Socket.ReceiveLength;
  if len <= 0 then Exit;

  i:= IndexOf(Socket.RemoteAddress);
  if (i < 0) or (i >= FClientLinks.Count) then Exit;

  pcl:=PClientLink(FClientLinks.Items[i]);

  SetLength(buf, len);
  FillChar(buf[0], Length(buf), 0);
  i:=0;
  j:=len;
//  while j>0 do
//  begin
    i:=pcl^.Socket.ReceiveBuf(buf[0], j);
//    Dec(j,i);
//  end;

//  savetofile(true, pcl.fs, buf);

  for i:= 0 to len - 1 do
  begin
    case pcl^.Setup of
    0:
      begin
        if buf[i]= $68 then
        begin
          pcl^.Buf[pcl^.Setup]:= buf[i];
          Inc(pcl^.Setup);
        end
        else
          pcl^.Setup:= 0;
      end;
    1:
      begin
        pcl^.Len:= buf[i];
        if (pcl^.Len >= 4) or (pcl^.Len <= BIGLEN - 2) then
        begin
          pcl^.Buf[pcl^.Setup]:= buf[i];
          Inc(pcl^.Setup);
        end
        else
          pcl^.Setup:= 0;
      end;
    2:
      begin
        ftype:= buf[i] and $03;
        pcl^.TESTFR:= True;
        if ftype in [$00, $02] then // I frame
        begin
          pcl^.Buf[pcl^.Setup]:= buf[i];
          pcl^.frameNo[0]:= buf[i] and $FC;
          Inc(pcl^.Setup);
        end
        else if ftype = $01 then // S frame
        begin
          //确认帧 先忽略
          pcl^.Setup:= 0
        end
        else if ftype = $03 then  // U frame
        begin
          try
            APDU:= buf[i] and $FC;

            if APDU = $04 then //询问数据传输
            begin
              SureSTARTDT(pcl^.Socket);
              pcl^.Ploy:= True; // 激活连接
              if not pcl^.First then
              begin
                SendZero(pcl);
                CallUp(pcl);
                pcl^.First:= True;
              end;
            end
            else
            if APDU = $10 then //询问停止
            begin
              SureSTOPDT(pcl^.Socket);
              pcl^.Ploy:= False;
              pcl^.First:= False;
            end
            else
            if APDU = $40 then // 询问连接
            begin
               SureTESTFR(pcl^.Socket);
            end;
          finally
            ClearClientLink(pcl^);
            pcl^.Setup:= 0;
          end;
        end;
      end;
    3, 4, 5:
      begin
        if pcl^.Setup = 3 then
          pcl.frameNo[1]:= buf[i];
        pcl^.Buf[pcl^.Setup]:= buf[i];
        Inc(pcl^.Setup);
      end;
    6..254:
      begin
        pcl^.Buf[pcl^.Setup]:= buf[i];
        Inc(pcl^.Setup);

        if pcl^.Setup >= pcl^.Len + 2 then
        begin
          pcl^.Setup:= 0;
          DealWith(pcl);
          SureFrame(pcl^.Socket, pcl.frameNo);
          ClearClientLink(pcl^);
//          if (pcl^.Setup < 12) then
//          begin
//            ClearClientLink(pcl^);
//            pcl^.Setup:= 0;
//            continue;
//          end;
//          try
//            DealWith(pcl);
//            SureFrame(pcl^.Socket, pcl.frameNo);
//          finally
//            ClearClientLink(pcl^);
//            pcl^.Setup:= 0;
//          end;
        end;
      end;

    end; // case
  end;
end;

procedure TSocket104.DealWith(pcl: PClientLink);
begin
  case pcl.Buf[6] of
  1, 3, 30, 31:
    begin
      DealWithYX(pcl) // 遥信
    end;
  //5, 9, 21, 32, 34:
  5, 32:
    begin
      DealWithYC(pcl) // 遥测
    end;
  45, 46, 57:
    begin
      DealWithYK(pcl) // 遥控
    end;
  100:
    begin
      DealWithCU(pcl) // 召唤
    end;
  end;
end;

procedure TSocket104.DealWithCU(pcl: PClientLink); // 召唤相应
var
  Reason: Byte;
begin
  //CON:= pcl^.buf[6];
  Reason:= pcl^.Buf[8] and $3F;

  if Reason = $0A then
    pcl^.CallUp := True;

  if Reason = $06 then
  begin
    // 不知道有没有
  end;  
end;

procedure TSocket104.DealWithYC(pcl: PClientLink);
var
  CON: Byte; //类型
  Add: Integer;   // 信息体地址
  Value: Single; // 开关
//  po: TgcDrawObject;
//  p: PEquipDesc;
  EleNum: Byte;
  SQ: Byte;
  i: Integer;
begin
  CON:= pcl^.buf[6];
  EleNum:= pcl^.buf[7] and $7F;
  SQ:= pcl^.buf[7] and $80;

  for i:= 0 to EleNum - 1 do
  begin
	  case CON of
    5:
      begin
        if SQ = 0 then
        begin
          if (15 + i*4) > BIGLEN - 1 then  Break;
          Add:= (PInteger(@(pcl^.buf[12 + i*5]))^ and $FFFFFF);
          Value:= pcl^.buf[15 + i*5] and $7F;
        end
        else if SQ = 1 then
        begin
          if (15 + i) > BIGLEN - 1 then Break;
          Add:= (PInteger(@(pcl^.buf[12]))^ and $FFFFFF) + i;
          Value:= pcl^.buf[15 + i] and $7F;
        end;
      end;
    32:
      begin
        if SQ = 0 then
        begin
          if (15 + 10*i) > BIGLEN - 1 then Break;
          Add:= (PInteger(@(pcl^.buf[12 + 12*i]))^ and $FFFFFF);
          Value:= pcl^.buf[15 + 12*i] and $7F;
        end
        else if SQ = 1 then
        begin
          if (15 + i) > BIGLEN - 1 then Break;
          Add:= (PInteger(@(pcl^.buf[12]))^ and $FFFFFF) + i;
          Value:= pcl^.buf[15 + i] and $7F;
        end;
      end;
    end;

{    po := find_sb_by_ycxh(Add);
    if po <> nil then
    begin
      p := po.data;
      TgcDrawText(po).Text := format('%.2f', [Value]);
      p^.YCValue := TgcDrawText(po).Text; //2002.04.22
      SetYcVirtualSbState(p, p^.YCValue);
    end;
    if regYczd then //2002.10.17 遥测整定
      fwMainForm.AutoADRK(fwmainForm.Apdcomport1, true);
}
  end;
end;

procedure TSocket104.DealWithYK(pcl: PClientLink);
var
  CON: Byte; //类型
  EleNum: Byte; // 信息元素(SQ=$80)或信息体的数目(SQ=$00)[0,128]
  Add: Integer;   // 信息体地址
  DCS:Byte; // 遥控状态 1 开 2 合
//  p: PEquipDesc;
  i: Integer;
  err_name: string;
  err_st: byte;
  SQ: Byte;
  Reason: Byte;
begin
  Add := 0;
  DCS:= 0;
  CON:= pcl^.buf[6];
  EleNum:= pcl^.buf[7] and $7F;
  SQ:= pcl^.buf[7] and $80;

  Reason:= pcl^.buf[8] and $3F;

  for i:= 0 to EleNum - 1 do
  begin
    if (CON = 45) or (CON = 46) then
    begin
      if pcl^.buf[7] <> 1 then Exit;
      if not Reason in [$06, $07] then Break;
      Add:= (PInteger(@pcl^.buf[12])^) and $FFFFFF;

      if (CON = 46) then //SQ
      begin
        DCS:= pcl^.buf[15] and $03;
        if (DCS = $01) or (DCS = $02) then
          DCS:= DCS - $01
        else
          Exit;
      end
      else
        DCS:= pcl^.buf[15] and $01;


      if Reason = $07 then
      begin
        {                                  1
        if Assigned(TaskRunForm) then
        begin
          //TaskRunForm.MonTimer.Enabled:= False;

        end;
        }
        Exit;
      end;

    end;

    if (CON = 57) and (SQ = 0) then
    begin
      if (15 + i*4) > BIGLEN - 1 then Break;
      if Reason <> $07 then Break;
      Add:= (PInteger(@pcl^.buf[12 + i*4])^ and $FFFFFF); //地址跳三
      DCS:= pcl^.buf[15 + i*4] and $03; //值跳三 B1
      if (DCS = $01) or (DCS = $02) then
        DCS:= DCS - $01
      else
        Continue;
    end;
    if (CON = 57) and (SQ = $80) then
    begin
      if (12 + i*3) > BIGLEN - 1 then Break;
      if Reason <> $07 then Break;

      Add:= (PInteger(@pcl^.buf[12])^ and $FFFFFF) + i;  //地址加1,值地址加2 B2
      DCS:= pcl^.buf[15 + i] and $03; //值跳三 B1
      if (DCS = $01) or (DCS = $02) then
        DCS:= DCS - $01
      else
        Continue;
    end;

{
    if (bStepSending or bLyTransTicket) then
    begin
      p := FindSb_byPrt(Add);
      if p <> nil then
      begin
        if (p^.name = gsbbh) and (DCS = gact) then
          //监控申请的操作与五防是一致的
          //cp.PutBlock(act, sizeof(act))
          AnswerAsk(pcl, Add, True)
        else
          //cp.PutBlock(nact, sizeof(nact));
          AnswerAsk(pcl, Add, False);
      end
      else
        //cp.PutBlock(nact, sizeof(nact));
        AnswerAsk(pcl, Add, False);
    end
    else
    begin
      if regCanUesBack then
      begin
        p := FindSb_byPrt(Add);
        //monsb1.fil,根据序号查找设备
        if p <> nil then
        begin
          if canoperate(p, DCS, err_name, err_st) = -1 then
            //可以操作
            //cp.PutBlock(act, sizeof(act))
            AnswerAsk(pcl, Add, True)
          else
            //cp.PutBlock(nact, sizeof(nact));
            AnswerAsk(pcl, Add, False);
        end
        else
          //cp.PutBlock(nact, sizeof(nact));
          AnswerAsk(pcl, Add, False);
      end
      else
        //cp.PutBlock(nact, sizeof(nact));
        AnswerAsk(pcl, Add, False);
    end;
    }
  end;
end;

procedure TSocket104.DealWithYX(pcl: PClientLink);
var
  CON: Byte; //类型
  SQ: Byte; // 单个/顺序[0, 1]
  Num: Byte; // 信息元素(SQ=$80)或信息体的数目(SQ=$00)[0,128]
  //BegAdd: Word; // 开始地址
  Add: Word;   // 信息体地址
  bPI: Byte; // 开关
  i: Integer;
begin
  CON:= pcl^.buf[6];
  Num:= pcl^.buf[7] and $7F;
  SQ:= pcl^.buf[7] and $80;
  for i:= 0 to Num - 1 do
  begin
    case CON of
    1: //单点
      begin
        if SQ = 0 then
        begin
          if (15 + i*4) > BIGLEN - 1 then  Break;
          Add:= (PInteger(@(pcl^.buf[12 + i*4]))^ and $FFFFFF);
          bPI:= pcl^.buf[15 + i*4] and $01;
        end
        else
        begin
          if (15 + i) > BIGLEN - 1 then Break;
          Add:= (PInteger(@(pcl^.buf[12]))^ and $FFFFFF) + i;
          bPI:= pcl^.buf[15 + i*2] and $01;
        end;
      end;
    3: //双点
      begin
        if SQ = 0 then
        begin
          if (15 + i*4) > BIGLEN - 1 then Break;
          Add:= (PInteger(@(pcl^.buf[12 + i*4]))^ and $FFFFFF);
          bPI:= pcl^.buf[15 + i*4] and $03;
          if bPI = 1 then
            bPI:= 0
          else if  bPI = 2 then
            bPI:= 1;
        end
        else
        begin
          if (15 + i) > BIGLEN - 1 then Break;
          Add:= (PInteger(@(pcl^.buf[12]))^ and $FFFFFF) + i;
          bPI:= pcl^.buf[15 + i*2] and $03;
          if bPI = 1 then
            bPI:= 0
          else if  bPI = 2 then
            bPI:= 1;
        end;
      end;
    30: //带时标的单点
      begin
        if SQ = 0 then
        begin
          if (15 + 10*i) > BIGLEN - 1 then Break;
          Add:= (PInteger(@(pcl^.buf[12 + 11*i]))^ and $FFFFFF);
          bPI:= pcl^.buf[15 + 11*i] and $01;
        end
        else
        begin
          if (15 + i) > BIGLEN - 1 then Break;
          Add:= (PInteger(@(pcl^.buf[12]))^ and $FFFFFF) + i;
          bPI:= pcl^.buf[15 + i] and $01;
        end;
      end;
    31: //带时标的双点
      begin
        if SQ = 0 then
        begin
          if (15 + i*10) > BIGLEN - 1 then
            Break;
          Add:= (PInteger(@(pcl^.buf[12 + 11*i]))^ and $FFFFFF);
          bPI:= pcl^.buf[15 + 11*i] and $03;
          if bPI = 1 then
            bPI:= 0
          else if  bPI = 2 then
            bPI:= 1;
        end
        else
        begin
          if (15 + i) > BIGLEN - 1 then Break;
          Add:= (PInteger(@pcl^.buf[12])^ and $FFFFFF) + i;
          bPI:= pcl^.buf[15 + i] and $03;
          if bPI = 1 then
            bPI:= 0
          else if  bPI = 2 then
            bPI:= 1;
        end;
      end;
    end; //case

    if Add < 4096 then
    begin
      try
        if (bPI = 0) or (bPI = 1) then
          SetSignalYX(Add, bPI);
      except
        MessageList.Add('遥信设置错误');
      end;
    end;
  end;
end;

procedure TSocket104.SetSignalYX(Add: Integer; bPI: Byte);//把遥信状态设置到操作票,add-顺序号,bPI是状态
var
  st: byte;
begin
  st := bPI;
end;

procedure TSocket104.ClearClientLink(var cl: ClientLink; init: Boolean = False);
begin
  with cl do
  begin
    if init then
    begin
      Socket:= nil;
      Ploy:= False; // 有没有激活连接
      CallUp:= False; // 有没有总召唤
      TESTFR:= False; // 网络是否连通
      STARTDT:= False; // 是否开始发送数据
      First:= False;
    end;
    FillChar(Buf[0], BIGLEN-1, 0);
    Setup:= 0;
    Len:= 0;
    frameNo[0]:= 0;
    frameNo[1]:= 0;
  end;
end;

procedure TSocket104.GetState(No: Integer; var Name, State: string);
begin
  if (No >= 0) and (No < FClientLinks.Count) then
  begin
    Name:= PClientLink(FClientLinks.Items[No])^.Socket.RemoteAddress;
    if PClientLink(FClientLinks.Items[No])^.Ploy = True then
      State:= '以激活的连接'
    else
      State:= '未激活的连接' ;
  end;
end;

function TSocket104.GetLCount: Integer;
begin
  Result:= FClientLinks.Count;
end;

procedure TSocket104.SaveToFile(const bsign: boolean; var tfs: textFile; const buf: array of byte);
var
  i: integer;
  s: string;
  sl: TStringlist;
begin
//    exit;
    if bsign then
      s:='五防收到  '
    else
      s:='五防发出  ';
    s:= s+datetimetostr(Now())+' : ' ;
    for i := 0 to length(buf) - 1 do
    begin
      s := s + format('%.2x ', [buf[i]]);
    end;
    WRITELN(TFS,S);
end;

procedure TSocket104.OnTimerCallUp(Sender: TObject);
var
  i:integer;
begin
  for i:= 0 to FClientLinks.Count - 1 do
  begin
    if(PClientLink(FClientLinks.Items[i])^.Ploy) then
    CallUp(PClientLink(FClientLinks.Items[i]));
  end;
end;

end.

⌨️ 快捷键说明

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