基于CMPP2.0的Socket客户端(Java)

短信验证码,短信通知等功能均可通过此Socket客户端实现。

注意事项如下:

1、服务器端是按字节依次读取的,所以客户端发送的字节包中的字段要严格按照CMPP协议中的顺序,而且每个字段都要有。

2、每个字段的实际长度不足时,用0补齐;电话号码后用空格补齐

3、使用ByteBuffer时,要注意putInt()和put()的区别


我亲身实践出来的模板如下,供大家参考学习:

public class Login {

 public static int pktLen;
   public static int reqId;
   public static int seqId;
   public static byte[] source_Addr = new byte[6];
   public static byte[] authenticatorSource = new byte[16];
   public static int timeStamp;
   public static byte version;

   private String strtimeStamp;
   private String loginPwd="xxxxxxxx";
   private String spId="123456";
   private String spPwd;
   
 public Login(int i)throws UnsupportedEncodingException,NoSuchAlgorithmException {
     pktLen = 39;
     reqId = 0x00000001;
     version = 0x10;
     seqId = i;
     source_Addr=spId.getBytes();
     SimpleDateFormat sf =  new SimpleDateFormat("MMddHHmmss");
     strtimeStamp = sf.format(new Date());
     timeStamp = Integer.valueOf(strtimeStamp).intValue();
     byte[] testa={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
     spPwd=spId+new String(testa)+loginPwd+strtimeStamp;
     authenticatorSource=Login.Md5(spPwd);
 }
  
 
  public static void main(String[] args) throws UnknownHostException, IOException, NoSuchAlgorithmException{
   Socket socket =null; 
   socket = new Socket("2xx.6x.10x.19x", 9890);   
       new Login(1);
       OutputStream os = socket.getOutputStream();  
    os.write(Login.toBytes());
    os.flush();
    InputStream inputStream = socket.getInputStream();  
              
    if((inputStream.read())==0)  
                  {  
                    System.out.println("login successfully");                     
                  }  
    
   os.write(Login.messageToBytes());
   os.flush();
   int a =0;
   inputStream.skip(25);
   while((a=inputStream.read())!=-1){
    System.out.println("RESULT: "+a);  
   }
  }

 private static byte[] Md5(String str)throws NoSuchAlgorithmException, UnsupportedEncodingException {
   MessageDigest md5 = MessageDigest.getInstance("MD5");
          md5.update(str.getBytes("UTF8"));
          byte[] temp;
          temp = md5.digest("".getBytes("UTF8"));
   return  temp; 
 }
 
 public static byte[] toBytes(){
  byte[] b = new byte[39];
     ByteBuffer bb = ByteBuffer.wrap(b, 0, 39);
     bb.order(ByteOrder.BIG_ENDIAN);
     bb.putInt(pktLen);
     bb.putInt(reqId);
     bb.putInt(seqId);
     bb.put(source_Addr);
     bb.put(authenticatorSource);
     bb.put(version);
     bb.putInt(timeStamp);
    
     return b;

 }
 public static byte[] messageToBytes(){
    int Total_Length=171;
    int Command_Id =4;
    int Sequence_Id = 2;
    byte[] Msg_id=new byte[8];
    byte PK_total=1;
    byte PK_number=1;
    byte Registered_Delivery=1;
    String Service_Id = "testmsg111";
    byte Msg_level=1;
    byte Fee_UserType=0;
    byte[] Fee_terminal_Id=new byte[21];
    byte TP_pId=0;
    byte TP_udhi=0;
    byte Msg_Fmt=0;
    byte[] Msg_src=new byte[6];
    byte[] FeeType=new byte[2];
    byte[] FeeCode=new byte[6];
    String ValId_Time = "00000000000000000";
    String At_Time = "00000000000000000";
    byte[] Src_Id=new byte[21];
    byte DestUsr_tl;
    byte[] Dest_terminal_Id=new byte[21];
    byte Msg_Length;
    byte[] Msg_Content;
    byte[] Reserve=new byte[8];
    Msg_src="200030".getBytes();
    FeeType="01".getBytes();
    FeeCode="000010".getBytes();
    Src_Id="1069034531           ".getBytes();
    DestUsr_tl=1;
    Dest_terminal_Id="18511790624          ".getBytes();
    Msg_Length=12;
    Msg_Content="digitalchina".getBytes();
    byte[] b = new byte[171];
    ByteBuffer bb = ByteBuffer.wrap(b, 0, 171);
    bb.order(ByteOrder.BIG_ENDIAN);
    bb.putInt(Total_Length);
    bb.putInt(Command_Id);
    bb.putInt(Sequence_Id);
    bb.put(Msg_id);
    bb.put(PK_total);
    bb.put(PK_number);
    bb.put(Registered_Delivery);
    bb.put(Msg_level);
    bb.put(Service_Id.getBytes());
    bb.put(Fee_UserType);
    bb.put(Fee_terminal_Id);
    bb.put(TP_pId);
    bb.put(TP_udhi);
    bb.put(Msg_Fmt);
    bb.put(Msg_src);
    bb.put(FeeType);
    bb.put(FeeCode);
    bb.put(ValId_Time.getBytes());
    bb.put(At_Time.getBytes());
    bb.put(Src_Id);
    bb.put(DestUsr_tl);
    bb.put(Dest_terminal_Id);
    bb.put(Msg_Length);
    bb.put(Msg_Content);
    bb.put(Reserve);
    bb.position();
    return b;
 }
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
功能特点: 1.遵照CMPP2.0协议实现,模拟了短信网关,支持CONNECT,SUBMIT,DELIVER,QUERY,CANCEL,TERMINATE消息。 2.支持多个客户端登录,支持单连接和双连接类型,支持标准CMPP和亚信API. 3.服务端自动生成Msgid,支持状态报告. 4.支持对客户端进行鉴权,用户可以自行配置有效的客户端ICPID,SPID,PWD,和有效的IP地址。 5.以二进制形式显示消息流内容,并且能够把消息包的每个字段都打印出来,当然这会影响一些效率。 6.模拟网关不对submit各字段的合法性进行判断(如msgsrc必须是企业代码icpid,srcid必须是接入号 发送错误代码介绍:0 = TRS_SUCCESS : 正确 1 = TRS_PACKET_ERR : 消息结构错 2 = TRS_CMD_ERR : 命令字错 3 = TRS_SEQ_DUPLICATE : 消息序号重复 4 = TRS_PACKET_LEN_ERR : 消息长度错 5 = TRS_FEE_ERR : 资费错 6 = TRS_MSG_LEN_ERR : 超过最大信息长 7 = TRS_SRV_CODE_ERR : 业务代码错 8 = TRS_FLUX_ERR : 流量控制错 9 = TRS_NOT_SRV_USER : 本网关不负责服务此计费号码,前转判断错(此SP不应发往本ISMG) 10 = TRS_SRC_ID_ERR : Src_Id错误 11 = TRS_MSG_SRC_ERR : Msg_src错误 12 = TRS_FEE_TERMINAL_ERR : Fee_terminal_Id错误 13 = TRS_DEST_TERMINAL_ERR : Dest_terminal_Id错误 160 = IP_ADDRESS_ERR : ZTE_EXTENED 帐号源IP地址错误 161 = LINK_FULL : ZTE_EXTENED 帐号已经建立了15条链路 162 = LOCK_MUTEX_ERR : ZTE_EXTENED 建链时锁错误 163 = RGSTRDDLVRY_ERR : ZTE_EXTENED Registered_Delivery取值错误 164 = FEEUSERTYPE_ERR : ZTE_EXTENED FeeUserType取值错误 165 = TERMINALTYPE_ERR : ZTE_EXTENED TerminalType取值错误 166 = MSGFMT_ERR : ZTE_EXTENED MsgFmt取值错误 167 = MSGFWDTYPE_ERR : ZTE_EXTENED msgFwdType取值错误 168 = USERTYPE_ERR : ZTE_EXTENED UserType取值错误 169 = ROUTE_ERR : ZTE_EXTENED 路由失败 170 = SMMC_ERR : ZTE_EXTENED 信息过滤失败 171 = IAGWM_LINK_DOWN : ZTE_EXTENED 与IAGW M模块断链 172 = SEND_AUTH_ERR : ZTE_EXTENED 给IAGW M模块发消息失败,非断链 173 = AUTH_ERR : ZTE_EXTENED IAGW M认证失败 174 = LICENSE_FAILED : ZTE_EXTENED 超过系统license限制 175 = TRANS_ERR : ZTE_EXTENED 消息转发错误 176 = RESP_TIME_OUT : ZTE_EXTENED 等resp超时 177 = FATAL_ERR : ZTE_EXTENED 当错误码为-1时转换为此值
CMPP (短消息协议) 是一种标准的短信中心和手机运营商之间的通信协议,常用于短信应用开发中。CMPP 2.0 是 CMPP 协议的一个版本,它规定了客户端(如手机应用或短信API)如何与短信中心交互以发送短信。 在CMPP 2.0客户端发送短信的基本步骤如下: 1. **初始化连接**: - 客户端需要连接到短信中心提供的IP地址和端口,并建立TCP连接。 - 双方通常会交换身份验证信息,例如用户名和密码,以验证客户端的身份。 2. **建立会话**: - 客户端发送一个请求,如SVC_USER或SVC_PASSTHROUGH,来创建一个服务会话,表明其功能需求。 3. **发送请求**: - 使用CMD_SEND短信命令,客户端准备一条短信的结构体,包含发送者、接收者、短信内容等信息。 - 在命令体中填充这些字段,并设置适当的标志,如短信类型(SMS_TYPE_NORMAL)。 4. **数据编码**: - 将短信内容转换为CMPP协议支持的编码格式,通常是7位ASCII或Unicode。 5. **发送命令**: - 客户端将命令打包成CMPP的消息体,并发送给短信中心。 6. **等待响应**: - 短信中心处理请求后,会返回一个响应,可能包含命令结果码和额外的信息。 7. **检查响应**: - 客户端解析响应,检查命令结果码是否成功(如ESME_ROK),确认短信是否已发送。 8. **关闭会话和连接**: - 如果发送成功,可以关闭会话并断开TCP连接,完成发送操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值