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

📄 u_ctthread.pas

📁 电信网关平台(V3.0)
💻 PAS
📖 第 1 页 / 共 2 页
字号:
      {    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 + -