2

我尝试实现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;

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

4

1 回答 1

1

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

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

于 2013-03-31T12:28:30.700 回答