目前,三大運營商都提供了自己的短信相關協議,比如聯通的SGIP協議、移動的CMPP協議、電信的SMPP協議,發送和接收短信、彩信可以根據運營商提供的接口,編寫相應的程序,以達到想要的功能。下面簡單介紹一下工作中遇到的使用聯通SGIP協議的問題。

發送短信比較簡單,客户端建立socket,先發送一個Bind請求,解析收到的BindResp包,正常連接後可以使用submit命令發送短信,獲取解析收到的submitresp包,發送成功後調用unbind命令斷開連接,解析收到的UnbindResp,如果命令操作正常就關閉socket,這就是一個發送短信的過程。

接收短信比較複雜一些,下圖為聯通SGIP接收短信的流程

聯通短信Java sdk_強制轉換

需要寫一個服務器端程序,實時的監聽聯通分配的某個端口,如果有數據來,就建立一個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());
			}
		}
	}