联通SGIP发送接收短信
目前,三大运营商都提供了自己的短信相关协议,比如联通的SGIP协议、移动的CMPP协议、电信的SMPP协议,发送和接收短信、彩信可以根据运营商提供的接口,编写相应的程序,以达到想要的功能。下面简单介绍一下工作中遇到的使用联通SGIP协议的问题。
发送短信比较简单,客户端建立socket,先发送一个Bind请求,解析收到的BindResp包,正常连接后可以使用submit命令发送短信,获取解析收到的submitresp包,发送成功后调用unbind命令断开连接,解析收到的UnbindResp,如果命令操作正常就关闭socket,这就是一个发送短信的过程。
接收短信比较复杂一些,下图为联通SGIP接收短信的流程
需要写一个服务器端程序,实时的监听联通分配的某个端口,如果有数据来,就建立一个socket,遵循上面的协议,打开连接,获取数据并解析,最后关闭socket。
具体的程序代码如下所示:
public void receiveMsg() { ServerSocket serversocket=null; Socket so=null; OutputStream output=null; InputStream input=null; SGIP_Command command=null; logger.info("Receive.receiveMsg执行..."); try { serversocket=new ServerSocket(this.request.iLocalPort); SGIP_Command tmpCMD=null; Deliver deliver=null; DeliverResp deliverresp = null; Report report=null; ReportResp reportresp=null; Userrpt userrpt = null; UserrptResp userrptresp = null; Bind active=null; Unbind term=null; BindResp resp=null; UnbindResp Unresp=null; boolean loop = true; int lastSeq = 0; List<SMSReceiveInfo> recVec = null; MobileSMTool tool = new MobileSMTool(); logger.info("监听端口发来的信息..."); while(true){ //服务器端程序一直监听端口 so=serversocket.accept(); logger.info("接收到客户端的一个连接.."); command=new SGIP_Command(); input=new DataInputStream(so.getInputStream()); output=new DataOutputStream(so.getOutputStream()); loop = true; recVec = new ArrayList<SMSReceiveInfo>(); while(loop) { tmpCMD=command.read(input);//接收sgip消息 logger.info("CommandID=" + command.getCommandID()); switch (command.getCommandID()) { case SGIP_Command.ID_SGIP_BIND : { logger.info("SGIP_Command.ID_SGIP_BIND..."); active=(Bind)tmpCMD;//强制转换 int result=active.readbody();//解包 logger.info("result=" + result); resp=new BindResp(this.request.iSrcNode,0); resp.write(output); logger.info("BIND_RESP完成"); break; } case SGIP_Command.ID_SGIP_UNBIND : { logger.info("SGIP_Command.ID_SGIP_UNBIND..."); term=(Unbind)tmpCMD;//强制转换 Unresp=new UnbindResp(this.request.iSrcNode); Unresp.write(output); //该会话结束 loop=false; break; } case SGIP_Command.ID_SGIP_DELIVER: { logger.info("SGIP_Command.ID_SGIP_DELIVER..."); deliver=(Deliver)tmpCMD;//强制转换 deliver.readbody();//解包 if(deliver.getSeqno_3() != lastSeq){ SMSReceiveInfo rec = new SMSReceiveInfo(); String content = ""; if(deliver.getMessageCoding() == 8){ content = new String(deliver.getMessageByte(), "UTF-16BE"); }else if(deliver.getMessageCoding() == 0 || deliver.getMessageCoding() == 15){ content = new String(deliver.getMessageByte(), "GB2312"); content = new String(content.getBytes("gb2312"), "utf8"); }else{ content = deliver.getMessageContent(); } rec.setContent(content); rec.setEncoding(deliver.getMessageCoding()); rec.setLength(deliver.getMessageLength()); rec.setNumber(deliver.getUserNumber()); recVec.add(rec); lastSeq = deliver.getSeqno_3(); }else{ loop = false; } deliverresp = new DeliverResp(this.request.iSrcNode,0); deliverresp.SetResult(0); deliverresp.write(output); break; } case SGIP_Command.ID_SGIP_REPORT: { logger.info("SGIP_Command.ID_SGIP_REPORT..."); report=(Report)tmpCMD;//强制转换 report.readbody();//解包 reportresp = new ReportResp(this.request.iSrcNode,0); reportresp.write(output); break; } case SGIP_Command.ID_SGIP_USERRPT: { logger.info("SGIP_Command.ID_SGIP_USERRPT..."); userrpt=(Userrpt)tmpCMD;//强制转换 userrpt.readbody(); //解包 userrptresp= new UserrptResp(this.request.iSrcNode,0); userrptresp.SetResult(12); userrptresp.write(output); break; } } Thread.sleep(1*500); } logger.info("一个会话结束..."); output.close(); input.close(); so.close(); if(recVec != null && recVec.size() > 0){ tool.dealReceiveMsg(recVec); } } } catch (SGIP_Exception e) { logger.error(e.toString()); } catch (Exception ex) { logger.error(ex.toString()); } finally { try { if(output != null){ output.close(); } if(input != null){ input.close(); } if(so != null){ so.close(); } } catch (Exception s) { logger.error(s.toString()); } } }