📄 u_ctthread.pas
字号:
{ end;
end
else
begin
new(xTCSubmit);
xTCSubmit^ := rSubmit;
SubmitList.Add(xTCSubmit);
end; }
except
end;
SocketBuff := nil;
end;
end;
procedure TCPSubmit.Receive;
var
Head: TSMGPHead;
CTSubmit_Resp: TSMGPDeliver_Resp;
SPResponse: PResponse;
CTRequestID: Longword;
CTsequence: Longword;
Status: Longword;
Rec_Len: Longword;
MID: string;
begin
FillChar(Head, sizeof(TSMGPHead), 0);
FillChar(CTSubmit_Resp, sizeof(TSMGPDeliver_Resp), 0);
CTRequestID := 0;
CTsequence := 0;
if CTClient.Connected then
if CTClient.WaitForData(timeout) then
begin
if sizeof(TSMGPHead) = CTClient.ReceiveBuf(Head, sizeof(TSMGPHead)) then
begin
Active_test_time := now; //下行链路回复时间
CTRequestID := HostToNet(Head.RequestID); //请求命令
CTsequence := HostToNet(Head.SequenceID); //序列号
Rec_Len := HostToNet(Head.PacketLength);
if Active_test_resp = CTRequestID then
begin {//电信发送链路测试回复}
StatuTxt := '【' + datetimetostr(now) + '】(MT)Active_Test_Resp 电信回复下行链路正常...' + inttostr(CTsequence) + #32;
LogList.AddLog('08' + StatuTxt);
synchronize(showstatu);
end
else if Submit_resp = CTRequestID then
begin {回馈报告Submit_response}
if CTClient.ReceiveBuf(CTSubmit_Resp, sizeof(TSMGPDeliver_Resp)) = sizeof(TSMGPDeliver_Resp) then
begin
Status := HostToNet(CTSubmit_Resp.Status);
if ((Status > 0) and (Status < 10)) or (Status = 39) then //返回这些代码的时候重发短信
ReSubmit(CTsequence, Status)
else if Status = 0 then
begin //电信网关正确接收
if not DeleteMT(CTsequence, MID) then //删除缓冲区短信 并返回MID
Statustr := '【' + datetimetostr(now) + '】删除缓冲区短信时没有返回正确的MID';
new(SPResponse);
SPResponse^.MID := MID;
strpcopy(SPResponse^.Submit_resp.MsgID, BCDToHex(CTSubmit_Resp.MsgID, sizeof(CTSubmit_Resp.MsgID)));
SPResponse^.Submit_resp.Status := Status;
ResponseList.Add(SPResponse); //放入下行回馈队列中
Statustr := '[' + datetimetostr(now) + ']Submit_Resp:';
Statustr := Statustr +'<CTsequence>' +inttostr(CTsequence) + #32;
Statustr := Statustr +'<Mid>' + Mid + #32;
Statustr := Statustr +'<Msgid>' + SPResponse^.Submit_resp.Msgid + #32;
Statustr := Statustr +'<Status>' + inttostr(Status);
LogList.AddLog('02' + Statustr);
synchronize(upmemo);
end
else
begin //返回其他错误代码
DeleteMT(CTsequence, MID); //删除缓冲区短信
new(SPResponse);
SPResponse^.MID := MID;
strpcopy(SPResponse^.Submit_resp.MsgID, BCDToHex(CTSubmit_Resp.MsgID, sizeof(CTSubmit_Resp.MsgID)));
SPResponse^.Submit_resp.Status := Status;
ResponseList.Add(SPResponse); //放入下行回馈队列中
Statustr := '【' + datetimetostr(now) + '】Submit_Resp:' + MID + '返回状态=' + inttostr(Status) + ',短消息已经被删除';
LogList.AddLog('09' + Statustr);
synchronize(upmemo);
end;
end;
end
else if Active_test = CTRequestID then
begin {电信发送链路检测包}
StatuTxt := '【' + datetimetostr(now) + '】CT-->SP(MT) ActiveTest ' + inttostr(CTsequence);
synchronize(showstatu);
MTActive_Test_Resp(CTsequence);
end
else if Exit_resp = CTRequestID then
begin
CTClient.Close;
SCanExit := True;
StatuTxt := '【' + datetimetostr(now()) + '】MT ExitCT 下行连接退出与电信的连接';
synchronize(showstatu);
end
else
begin //错误的包头命令字
try
SetLength(ErrMsg, Rec_Len - 12);
CTClient.ReceiveBuf(ErrMsg, Rec_Len - 12);
//SetLength(ErrMsg, 0);
ErrMsg := nil;
except
end;
StatuTxt := '【' + datetimetostr(now()) + '】MT 接收到类型错误的消息包';
synchronize(showstatu);
end;
end;
end;
{else begin
CTClient.Close;
HadLogin := False;
SCanExit := True;
StatuTxt := '【' + datetimetostr(now) + '】(MT)接收等待超时,链路关闭,等待' + inttostr(RetryTime div 1000) + '秒重新登陆';
synchronize(showstatu);
sleep(RetryTime);
end;}
end;
procedure TCPSubmit.MTActive_Test_Resp(CTsequence: Longword);
var
spActiveTest_Resp: TSMGPHead;
begin
FillChar(spActiveTest_Resp, sizeof(TSMGPHead), 0);
spActiveTest_Resp.SequenceID := HostToNet(CTsequence);
spActiveTest_Resp.PacketLength := HostToNet(sizeof(TSMGPHead));
spActiveTest_Resp.RequestID := HostToNet(Active_test_resp);
if CTClient.Connected then
if sizeof(TSMGPHead) = CTClient.SendBuf(spActiveTest_Resp, sizeof(TSMGPHead)) then
begin
StatuTxt := '【' + datetimetostr(now()) + '】SP-->CT(MT)ActiveTest_Resp SP回复下行链路正常... ' + inttostr(CTsequence);
synchronize(showstatu);
end;
end;
procedure TCPSubmit.ReSubmit(SequenceID, statu: Longword);
var
i: integer;
cSubmit: PxSubmit;
aList: TList;
MID: string;
begin
aList := SaveSubmitList.LockList;
try
for i := 0 to aList.count - 1 do
begin
cSubmit := PxSubmit(aList.Items[i]);
if SequenceID = cSubmit^.SequenceID then
if cSubmit^.Resend >= sendtimes then
begin //重发4次失败,不再重发
MID := cSubmit^.sSubmit.MID;
dispose(cSubmit);
aList.Delete(i);
StatustrE := '【' + datetimetostr(now()) + '】Submit_Resp MID=' + MID + ' 电信网关返回状态=' + inttostr(statu) + '序列号=' + inttostr(SequenceID) + ',第4发送次失败,短消息已被删除';
LogList.AddLog('09' + StatustrE);
synchronize(showError);
break;
end
else
begin
SubmitList.Add(cSubmit);
aList.Delete(i);
MID := cSubmit^.sSubmit.MID;
StatustrE := '【' + datetimetostr(now()) + '】Submit_Resp MID=' + MID + ' 电信网关返回状态=' + inttostr(statu) + '发送失败,等待再发...';
synchronize(showError);
break;
end;
end;
finally
SaveSubmitList.UnlockList;
end;
end;
function TCPSubmit.DeleteMT(SequenceID: Longword; var aMid: string): boolean; //回馈报告
var
i, FirstCount: integer;
cSubmit: PxSubmit;
aList: TList;
begin
Result := False; //返回MID
aList := SaveSubmitList.LockList;
FirstCount := aList.count - 1; //列表初始元素个数
try
for i := FirstCount downto 0 do //扫描保存区列表一遍
begin
cSubmit := PxSubmit(aList.Items[i]);
if SequenceID = cSubmit^.SequenceID then
begin
aMid := cSubmit^.sSubmit.MID; //返回MID
dispose(cSubmit);
aList.Delete(i);
Result := True;
end
else
begin {SaveSubmitList中有还没有回馈报告回来的短信}
if minutesBetween(now, cSubmit^.Then_DateTime) > resptime then {大于10分钟没有回回馈报告重发}
begin
SubmitList.Add(cSubmit);
aList.Delete(i);
Statustr := '【' + datetimetostr(now()) + '】MID=' + #32 + cSubmit^.sSubmit.MID + #32 + '在发送' + inttostr(resptime) + '分钟后仍未接收到电信回馈报告,网关作重发处理';
synchronize(upmemo);
LogList.AddLog('07' + Statustr);
end;
end;
end;
finally
SaveSubmitList.UnlockList;
end;
end;
procedure TCPSubmit.upmemo;
begin
if SMGPGateWay.Memo1.Lines.count > 500 then SMGPGateWay.Memo1.Clear;
if SMGPGateWay.N3.Checked then
SMGPGateWay.Memo1.Lines.Add(Statustr + #13#10);
SMGPGateWay.StatusBar1.Panels[7].Text := 'T: ' + inttostr(SPS_cou);
SMGPGateWay.StatusBar1.Refresh;
end;
procedure TCPSubmit.showError;
begin
if SMGPGateWay.Memo1.Lines.count > 500 then SMGPGateWay.Memo1.Clear;
if SMGPGateWay.N2.Checked then
SMGPGateWay.Memo1.Lines.Add(StatustrE + #13#10);
end;
procedure TCPSubmit.showstatu;
begin
if SMGPGateWay.MeMO3.Lines.count > 1000 then SMGPGateWay.MeMO3.Clear;
SMGPGateWay.MeMO3.Lines.Add(StatuTxt);
end;
procedure TCPSubmit.AddCou;
begin
if SPS_cou > 2147483600 then SPS_cou := 1;
inc(SPS_cou);
end;
procedure TCPSubmit.AddsSeq;
begin
if sSequence >= 4294967200 then sSequence := 1;
sSequence := sSequence + 1;
end;
function TCPSubmit.SubmitButDisConn(DisConnTime: TDateTime): integer;
var
i, FirstCount: integer;
cSubmit: PxSubmit;
aList: TList;
SPResponse: PResponse;
begin
Result := 0; //返回MID
aList := SaveSubmitList.LockList;
FirstCount := aList.count - 1; //列表初始元素个数
try
for i := FirstCount downto 0 do //扫描保存区列表一遍
begin
cSubmit := PxSubmit(aList.Items[i]);
if SecondsBetween(DisConnTime, cSubmit^.Then_DateTime) <= 5 then //下行链路断开前5秒没有回复回馈报告的不重发
begin
inc(Result);
new(SPResponse);
SPResponse^.MID := cSubmit^.sSubmit.MID;
SPResponse^.Submit_resp.Status:=0;
strpcopy(SPResponse^.Submit_resp.MsgID, '1186185' + formatdatetime('yymmddhhnn', now) + format('%.3d', [Result])); //手动生成MsgID
ResponseList.Add(SPResponse); //放入下行回馈队列中
Statustr := '【' + datetimetostr(now) + '】短信MID=' + #32 + cSubmit^.sSubmit.MID + #32 + '刚下发链路断开没有收到回馈报告,系统不作重发处理并当作电信网关已经成功接受';
dispose(cSubmit);
aList.Delete(i);
synchronize(upmemo);
LogList.AddLog('07' + Statustr);
end;
end;
finally
SaveSubmitList.UnlockList;
end;
end;
procedure TCPSubmit.NoResponse_Resubmit;
var
i, FirstCount: integer;
cSubmit: PxSubmit;
aList: TList;
begin
aList := SaveSubmitList.LockList;
FirstCount := aList.count - 1; //列表初始元素个数
try
for i := FirstCount downto 0 do //扫描保存区列表一遍
begin
cSubmit := PxSubmit(aList.Items[i]);
{SaveSubmitList中有还没有回馈报告回来的短信}
if minutesBetween(now, cSubmit^.Then_DateTime) > resptime then {大于10分钟没有回回馈报告重发}
begin
SubmitList.Add(cSubmit);
aList.Delete(i);
Statustr := '【' + datetimetostr(now()) + '】MID=' + #32 + cSubmit^.sSubmit.MID + #32 + '在' + inttostr(resptime) + '分钟后没有接收到电信回馈报告,网关作重发处理';
synchronize(upmemo);
LogList.AddLog('07' + Statustr);
end;
end;
finally
SaveSubmitList.UnlockList;
end;
end;
function TCPSubmit.MakeSockBuff(var SubmitLen: integer; rSubmit: xSubmit): Longword;
var
i, count: integer;
onenumber, Source: string;
tmpBuf: array[0..20] of char;
{2.0协议后}
SMGPSubmit2011: TSMGPSubmit2011; //包头+包体1
SMGPSubmit203: TSMGPSubmit203; //包体3
SMGPTLV_tag:TSMGPTLV_tag;
SMGPTLVLinkID_tag:TSMGPTLVLinkID_tag;
begin
Result := 0;
FillChar(SMGPSubmit2011, sizeof(TSMGPSubmit2011), 0);
FillChar(SMGPSubmit203, sizeof(TSMGPSubmit203), 0);
with SMGPSubmit203 do //包体3
begin
count := rSubmit.sSubmit.DestTermIDCount; //号码数
Source := rSubmit.sSubmit.DestTermID; //号码列表
if count > 1 then
begin
for i := 0 to count - 1 do
begin
FillChar(tmpBuf, sizeof(tmpBuf), 0);
Source := ChtchOne(Source, onenumber); //获取单个号码
strpcopy(tmpBuf, onenumber);
move(tmpBuf, DestTermID[i * 21], 21);
end;
end
else
strpcopy(DestTermID, Source);
DestTermIDCount := count;
strpcopy(SrcTermID, rSubmit.sSubmit.SrcTermID);
strpcopy(ChargeTermID, rSubmit.sSubmit.ChargeTermID);
MsgLength := rSubmit.sSubmit.MsgLength;
strpcopy(MsgContent, rSubmit.sSubmit.MsgContent);
end;
SubmitLen := sizeof(TSMGPSubmit2011) + sizeof(TSMGPSubmit203) - 252 - 21 * (MAx_UserNumber - count) + SMGPSubmit203.MsgLength + 34; //34长度是可选参数中的三种 linkID submitmsgtype, spdealresult
//包头和包体1
with SMGPSubmit2011 do
begin
Head.PacketLength := winsock.Htonl(SubmitLen);
Head.RequestID := winsock.Htonl(Submit);
Head.SequenceID := winsock.Htonl(sSequence);
body.MsgType := rSubmit.sSubmit.MsgType;
body.NeedReport := rSubmit.sSubmit.NeedReport;
body.Priority := rSubmit.sSubmit.Priority;
body.MsgFormat := rSubmit.sSubmit.MsgFormat;
strpcopy(body.ServiceID, rSubmit.sSubmit.ServiceID);
strpcopy(body.FeeType, rSubmit.sSubmit.FeeType);
strpcopy(body.FeeCode, rSubmit.sSubmit.FeeCode);
strpcopy(body.FixedFee, rSubmit.sSubmit.FixedFee);
body.MsgFormat := rSubmit.sSubmit.MsgFormat;
strpcopy(body.ValidTime, rSubmit.sSubmit.ValidTime);
strpcopy(body.ATTime, rSubmit.sSubmit.ATTime);
end;
//===========================================================
SetLength(SocketBuff, SubmitLen);
FillChar(SocketBuff[0], SubmitLen, 0);
move(SMGPSubmit2011, SocketBuff[0], 74);
move(SMGPSubmit203, SocketBuff[74], 43);
move(SMGPSubmit203.DestTermID, SocketBuff[74 + 43], 21 * count);
move(SMGPSubmit203.MsgLength, SocketBuff[74 + 43 + 21 * count], 1);
move(SMGPSubmit203.MsgContent, SocketBuff[74+ 43 + 21 * count + 1], SMGPSubmit203.MsgLength);
move(SMGPSubmit203.Reserve, SocketBuff[74 + 43 + 21 * count + 1 + SMGPSubmit203.MsgLength], 8);
//封装可选参数
FillChar(SMGPTLVLinkID_tag,sizeof(TSMGPTLVLinkID_tag), 0);
SMGPTLVLinkID_tag.Tag := winsock.htons(TLV_Lab_LinkID);
SMGPTLVLinkID_tag.Length:=winsock.htons(20);
// move(rSubmit.sSubmit.LinkID, SMGPTLVLinkID_tag.Value, 20);
strpcopy(SMGPTLVLinkID_tag.Value, rSubmit.sSubmit.LinkID);
move(SMGPTLVLinkID_tag, SocketBuff[74 + 43 + 21 * count + 1 + SMGPSubmit203.MsgLength+8], 24);
FillChar(SMGPTLV_tag,sizeof(TSMGPTLV_tag),0);
SMGPTLV_tag.Tag:=winsock.htons(TLV_Lab_SubmitMsgType);
SMGPTLV_tag.Length:=winsock.htons(1);
SMGPTLV_tag.Value := rSubmit.sSubmit.SubmitMsgType;
move(SMGPTLV_tag, SocketBuff[74 + 43 + 21 * count + 1 + SMGPSubmit203.MsgLength+8 + 24], 5);
FillChar(SMGPTLV_tag,sizeof(TSMGPTLV_tag),0);
SMGPTLV_tag.Tag:=winsock.htons(TLV_Lab_SPDealReslt);
SMGPTLV_tag.Length:=winsock.htons(1);
SMGPTLV_tag.Value:=0;
move(SMGPTLV_tag, SocketBuff[74 + 43 + 21 * count + 1 + SMGPSubmit203.MsgLength+8 + 24+5], 5);
Result := HostToNet(SMGPSubmit2011.Head.SequenceID); //返回包序列号
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -