📄 rule104.pas
字号:
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 + -