首先尝试SMPP协议(绑定命令)

时间:2013-03-31 11:05:13

标签: delphi smpp

我尝试实现 SMPP 客户端,第一个测试是在我有实时套接字连接后进行绑定。

但服务器在收到信息流时显示 HEX错误信息

SMPP单位

interface
  uses Classes;
Type
 // c octet strings
  TSystemID = string[16];
  TPassword = string[9];
  TSystemType = string[13];
  TAddr = string[21];
  TAddr_Range = string[41];
  TSvc_Type = string[6];
  TDate_time = string[17];
  TMsgID = string[65];
pPDU_HDR = ^TPDU_HDR;

TPDU_HDR = packed record
    command_len : LongWord ;
    command_id  : LongWord ;
    command_status :LongWord ;
    command_number:LongWord ;
end;

pSMPP_BIND = ^TSMPP_BIND ;
TSMPP_BIND = packed record
  SystemID : TSystemID ;
  Password : TPassword ;
  SystemType : TSystemType ;
  Ver        : Byte;
  Addr_TON   : Byte ;
  Addr_NPI   : Byte ;
  Addr_Range : TAddr_Range ;
end;
const
  { max short message length }
  DCS7_MAX_LEN = 160;
  DCS8_MAX_LEN = 140;
  DCSUCS2_MAX_LEN = DCS8_MAX_LEN div 2;
  { command ids }
  cmdNull   = $00000000;
  cmdBindReceiver = $00000001;
  cmdBindTransmitter = $00000002;
  cmdQuery = $00000003;
  cmdReplace = $00000007;
  cmdCancel = $00000008;
  cmdBindTransceiver = $00000009;
  cmdOutbind = $0000000B;
  cmdUnbind = $00000006;
  cmdSubmitSM = $00000004;
  cmdDeliverSM = $00000005;
  cmdEnquireLink = $00000015;
  cmdSubmitMultiply = $00000021;
  cmdAlertNotification = $00000102;
  cmdData = $00000103;
  cmdGenericNack = $80000000;
  cmdResponseBase = $80000000;
  cmdBindReceiverResponse = $80000001;
  cmdBindTransmitterResponse = $80000002;
  cmdQueryResponse = $80000003;
  cmdReplaceResponse = $80000007;
  cmdCancelResponse = $80000008;
  cmdBindTransceiverResponse = $80000009;
  cmdUnbindResponse = $80000006;
  cmdSubmitSMResponse = $80000004;
  cmdDeliverSMResponse = $80000005;
  cmdEnquireLinkResponse = $80000015;
  cmdSubmitMultiplyResponse = $80000021;
  cmdDataResponse = $80000103;
  { ESM_CLASS }
  ESM_CLASS_DELIVERY_RECEIPT = $04;
  ESM_CLASS_UDHI = $40;
implementation
end.

在我的表格上btnSendBindClick

procedure TFrmMain.btnSendBindClick(Sender: TObject);
var  hdr : TPDU_HDR ;
     bind_pkt : TSMPP_BIND ;
     mm : TMemoryStream ;
     HdrPtr : pPDU_HDR ;
     BindPtr : pSMPP_BIND ;
     sysid : AnsiString ;
     pass  : AnsiString ;
     systype : AnsiString ;
     add_rn : AnsiString ;
begin

sysid := 'sysid';
pass := 'pass';
systype := 'sys_type';
add_rn := '';

hdr.command_id := htonl(cmdBindTransceiver)  ;
hdr.command_status := htonl(cmdNull) ;
hdr.command_number  :=  htonl(cmdBindTransmitter)  ;
hdr.command_len := htonl(SizeOf(hdr)+SizeOf(bind_pkt)); 

bind_pkt.SystemID := pansiChar(sysid);
bind_pkt.Password := pansiChar(pass);
bind_pkt.SystemType := pansiChar(systype);
bind_pkt.Ver := 0 ;
bind_pkt.Addr_TON := 1 ;
bind_pkt.Addr_NPI := 1 ;
bind_pkt.Addr_Range := pansiChar(add_rn);

HdrPtr  := @HdrPtr ;
BindPtr := @bind_pkt ;

mm := TMemoryStream.Create ;
mm.Write(HdrPtr^,SizeOf(hdr));
mm.Position := mm.Size;
mm.Write(BindPtr^,SizeOf(bind_pkt));
mm.Position := 0 ;

clnt.Socket.SendStream(mm);

end;

我认为我需要将数据流编码为某些东西,但我不确定。

1 个答案:

答案 0 :(得分:1)

我上次在1999/2000年与SMPP合作,但那时,规格。 3.4表示像SystemID,Password等字段,即声明为 Var。 Max nn ,类型为 C-OctetString

因此,如果规范没有改变,你就完全错过了它:你不能使用记录和类似的数据结构,但你必须创建一个包含ASCIIZ字符串序列的八位字节流,没有填充,例如(使用Delphi语法): ...'SystemId'#0'Password'#0'SystemType'#0 ... 。如果我没记错,你也应该为整数字段更改字节序。