目前,三大運營商都提供了自己的短信相關協議,比如聯通的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());
}
}
}