目前,三大运营商都提供了自己的短信相关协议,比如联通的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 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();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());}}}