⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spsmsservice2.java

📁 采用JAVA开发
💻 JAVA
字号:
package com.gctech.sms.sp;

import java.io.IOException;
import org.apache.log4j.Logger;
import java.io.InputStream;
import com.gctech.util.Tools;
import com.gctech.sms.dao.SpLoginInfoDao;
import com.gctech.util.MD5;
import java.io.OutputStream;
import java.io.DataInputStream;
import com.gctech.sms.msg.MTInfo;
import com.gctech.sms.platform.MTDispatcher;
import com.gctech.sms.util.ThreadManager;
import java.util.List;
import java.util.Vector;
import java.net.Socket;
import com.gctech.sms.sp.msg.SubscribeResp;
import com.gctech.sms.sp.msg.MsgHead;
import com.gctech.sms.msg.MTAck;
import com.gctech.sms.sp.msg.UnsubscribeResp;
import com.gctech.sms.vo.SpLoginInfo;
import EDU.oswego.cs.dl.util.concurrent.Sync;
import com.gctech.sms.msg.StructConverter;
import com.gctech.util.net.SocketService;

/**
 * <p>Title: 给SP提供的短信服务器,此接口适应sp短信接口1.1版本
 * 原有的SpSmsService继续保留使用
 * </p>
 * <p>Description: 给SP提供的短信服务器,需要认证。</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: gctech</p>
 * @author 李家智
 * @version $Id: SpSmsService2.java,v 1.2 2005/01/14 05:29:02 lijz Exp $
 */

public class SpSmsService2 extends SpSmsService {

	public SpSmsService2() {
		super();
		mtSendOut = new Vector();
	}
	OutputStream out;
	private String spId;
	private List mtSendOut;

	static final int SUCESS = 0;
	static final int ERROR_DATA_LENGTH = 1;
	static final int WRONG_CLIENT_IP = 2;
	static final int MD5_ERROR = 3;
	static final int SP_NOT_FOUND = 4;
	//超时时间,3分钟
	static final int TIME_OUT = 3 * 60 * 1000;

	/**
	 * 订阅应答。不在支持此方法
	 * */
	void subscribResp(byte[] subscribResp) {
		String msgId = new String(subscribResp, 12, 20).trim();
		SubscribeResp resp = new SubscribeResp();
		resp.setMsgId(msgId);
		MsgHead head = new MsgHead();
		head.setCommandStatus(Tools.byte2int(subscribResp, 4));
		resp.setMsgHead(head);
		SpServer server = SpServer.getInstance();
		Object obj = server.putSubscribeResp(msgId, resp);
		if (obj instanceof Sync) {
			Sync lock = (Sync) obj;
			//解锁
			lock.release();
		} else {
			logger.warn(obj);
			server.removeSubResp(msgId);
		}
	}

	/**
	 * 退订应答。不在支持此方法
	 * */
	void unsubscribResp(byte[] unsubscribResp) {
		String msgId = new String(unsubscribResp, 12, 20).trim();
		UnsubscribeResp resp = new UnsubscribeResp();
		resp.setMsgId(msgId);
		MsgHead head = new MsgHead();
		head.setCommandStatus(Tools.byte2int(unsubscribResp, 4));
		resp.setMsgHead(head);
		logger.debug(resp);
		SpServer server = SpServer.getInstance();
		Object obj = server.putUnsubscribeResp(msgId, resp);
		if (obj instanceof Sync) {
			Sync lock = (Sync) obj;
			//解锁
			lock.release();
		} else {
			logger.warn(obj);
			server.removeSubResp(msgId);
		}

	}

	/***
	 * 下行消息。
	 * */
	void submit(byte[] submitReq) {
		logger.debug(new String(submitReq));
		try {
			String theSpId = new String(submitReq, 12, 20).trim();
			if (spId.equals(theSpId)) {
				//启动线程分拣下行短信。
				SubmitTask2 task = new SubmitTask2(submitReq, out);
				ThreadManager.getInstance().execute(task);
			} else {
				//SP ID和登录的不相同
				logger.warn("the spId are not equal!");
			}
		} catch (InterruptedException ex) {
			logger.error(ex, ex);
		}
	}

	/**
	 * 退出回应。
	 * */
	void exitResp(byte[] exitReq) throws IOException {
		byte[] exitResp = new byte[16];
		Tools.int2byte(16, exitResp, 0);
		Tools.int2byte(Constants.EXIT_RES, exitResp, 4);
		System.arraycopy(exitReq, 8, exitResp, 12, 4);
		send(exitResp);
		sock.close();
	}

	/**
	 * 检测消息回复。
	 * */
	void activeTestResp(byte[] activeTest) throws IOException {
		byte[] activeResp = new byte[16];
		Tools.int2byte(16, activeResp, 0);
		Tools.int2byte(Constants.ACTIVE_TEST_RES, activeResp, 4);
		System.arraycopy(activeTest, 8, activeResp, 12, 4);
		send(activeResp);
	}
	synchronized void send(byte[] data) throws IOException {
		int cmdId = Tools.byte2int(data, 4);
		//    System.out.println(cmdId);
		//    System.out.println("spip="+sock.getInetAddress().getHostAddress());
		//System.out.println("port=" + sock.getPort());
		out.write(data);
	}

	//运行服务
	void doService() throws IOException {
		while (sock != null && sock.isConnected()) {
			//读消息头
			DataInputStream in = new DataInputStream(sock.getInputStream());
			//读取长度
			int msgLength = in.readInt();
			logger.debug("receive msgSize is:" + msgLength);
			//正确的消息
			if (msgLength >= 16 && msgLength <= 2048) {
				//读取数据
				byte[] resp = new byte[msgLength - 4];
				in.read(resp);
				//处理数据
				int cmdId = Tools.byte2int(resp);
				switch (cmdId) {
					//检测消息
					case Constants.ACTIVE_TEST_REQ :
						activeTestResp(resp);
						break;
						//退出消息
					case Constants.EXIT_REQ :
						exitResp(resp);
						break;
						//下行短信消息
					case Constants.SUBMIT_REQ :
						//异步发送消息。
						submit(resp);
						break;
						//订阅应答
					case Constants.SUBSCRIBE_RES :
						subscribResp(resp);
						break;
						//退订应答
					case Constants.UNSUBSCRIBE_RES :
						unsubscribResp(resp);
						break;
					default :
						logger.warn("can't found the cmdId:" + cmdId);
						break;
				}
			} else {
				throw new IOException("data length error:" + msgLength);
			}
		}
	}

	public static void main(String[] args) {
		System.out.println("192.168.171.31".matches(".*"));
		System.out.println("192.168.171.31".matches("192.168.171.31"));
		System.out.println("192.168.171.31".matches("192.168.171.4324"));
	}
	public void run() {
		spId = "UNKNOW";
		String clientIp = "UNKNOW";
		try {
			sock.setSoTimeout(TIME_OUT);
			int status = SUCESS;
			byte[] authSvr = null;
			//获取client ip
			clientIp = sock.getInetAddress().getHostAddress();
			//此处接收一个登录信息
			InputStream in = sock.getInputStream();
			byte[] data = new byte[Constants.LOGIN_MSG_LENGTH];
			int rt = in.read(data);
			if (rt != Constants.LOGIN_MSG_LENGTH) {
				logger.warn("从" + clientIp + "的连接包数据长度错误" + rt);
				status = ERROR_DATA_LENGTH;
			} else {
				//取出spId
				spId = new String(data, 16, 20).trim();
				//查询出SP信息。
				SpLoginInfo login = SpLoginInfoDao.findByPk(spId);
				if (login == null) {
					logger.warn("不能找到 " + spId + " 登录信息!");
					status = SP_NOT_FOUND;
					//
					//}else if (login.getClientIp().equals(clientIp)) {
				} else if (clientIp.matches(login.getClientIp())) {
					//取出时间戳
					String timestamp = "" + Tools.byte2int(data, 52);
					System.out.println("timestamp is " + timestamp + ".");
					if (timestamp.length() < 10) {
						timestamp = "0" + timestamp;
					}
					logger.debug(timestamp);
					//计算明文长度
					int plainLen = 20 + 7 + login.getSharedSecret().getBytes().length + 10;
					logger.debug("plainLen:" + plainLen);
					byte[] plain = new byte[plainLen];
					//拼凑明文
					System.arraycopy(data, 16, plain, 0, 20); //copy spid
					byte[] temp = login.getSharedSecret().getBytes();
					System.arraycopy(temp, 0, plain, 27, temp.length); //copy secret
					int start = 27 + temp.length; //the timestart postion

					temp = timestamp.getBytes();
					logger.debug("temp:" + temp.length);
					logger.debug("start:" + start);
					System.arraycopy(temp, 0, plain, start, 10);

					//MD5
					MD5 md5 = new MD5();
					logger.debug("plain:" + new String(plain));
					logger.debug("after md5:" + md5.getMD5ofStr(plain, plain.length));
					byte[] md5Msg = md5.getMD5ofBytes(plain, plain.length);
					//short dddd = md5Msg[16];
					//logger.debug("ddddd " +dddd);
					//校验md5
					logger.debug("input md5");
					boolean authen = true;
					for (int i = 0; i < 16; i++) {
						System.out.print(md5.byteHEX(data[36 + i]));
						if (md5Msg[i] == data[36 + i]) {
						} else {

							authen = false;
							break;
						}
					}
					String authenClient = new String(data, 36, 16);
					//int a1 = Tools.byte2int(data,36);
					/*for (int i = 0;i<16;i++){
					  short ddd = data[36+i];
					  logger.debug("ddd"+i+" " + ddd);
					}*/

					if (authen) {
						//生成server端MD5
						//程序修改2004-7-2 wjl
						byte[] svrPlain = new byte[(status + authenClient + login.getSharedSecret()).getBytes().length];
						//byte[] svrPlain = (status + authenClient + login.getSharedSecret()).getBytes();
						//byte[] svrPlain = (authenClient).getBytes();
						Tools.int2byte(status, svrPlain, SUCESS);
						System.arraycopy(data, 36, svrPlain, 1, 16);
						temp = login.getSharedSecret().getBytes();
						System.arraycopy(temp, 0, svrPlain, 17, temp.length);
						logger.debug("生成server端MD5 " + status + authenClient + login.getSharedSecret());

						authSvr = md5.getMD5ofBytes(svrPlain, svrPlain.length);
						//authSvr = svrPlain;
						/*for (int i = 0;i<svrPlain.length;i++){
						  short ddd = svrPlain[i];
						  logger.debug("eeee"+i+" " + ddd);
						}*/
						logger.debug("authSvr " + new String(authSvr));
					} else {
						logger.debug(authenClient + " VS " + new String(md5Msg));
						status = this.MD5_ERROR;
					}
				} else {
					logger.warn("SP " + spId + " 从" + clientIp + "发过来的请求错误,正确的IP应该是:" + login.getClientIp());
					status = WRONG_CLIENT_IP;
				}
			}
			//回复消息
			out = sock.getOutputStream();
			byte[] loginResp = new byte[32];
			Tools.int2byte(32, loginResp, 0);
			Tools.int2byte(Constants.LOGIN_RES, loginResp, 4);
			Tools.int2byte(status, loginResp, 8);
			//复制序列号
			System.arraycopy(data, 12, loginResp, 12, 4);
			if (status == this.SUCESS) {
				System.arraycopy(authSvr, 0, loginResp, 16, 16);
				System.out.println("onwser spip=" + sock.getInetAddress().getHostAddress());
				out.write(loginResp);
				SpServer.getInstance().register(this);
				logger.info(" Register " + spId + " from " + clientIp + "\t\t\t\t\t\t[OK]");
				doService();
			} else {
				logger.debug("status:" + status);
				out.write(loginResp);
				sock.close();
				sock = null;
			}
		} catch (Throwable e) {
			logger.error(e, e);
		} finally {
			if (sock != null) {
				try {
					sock.close();
				} catch (Throwable ex) {
					logger.error(ex, ex);
				}
				sock = null;
			}
			SpServer.getInstance().unregister(this);
			logger.info("释放从" + spId + ":" + clientIp + "过来的连接 \t\t\t\t\t\t[成功]");
		}
	}
	public String getSpId() {
		return spId;
	}

	static final Logger logger = Logger.getLogger(SpSmsService2.class);
}

class SubmitTask2 implements Runnable {
	byte[] submitReq;
	OutputStream out;
	public SubmitTask2(byte[] submitReq, OutputStream out) {
		this.submitReq = submitReq;
		this.out = out;
	}
	public void run() {
		//组织消息,采用sp2.0
		MTInfo info = StructConverter.struct2ToMt(submitReq);
		//info.gateway = 8;
		//增加到发送列表
		MTAck ack = MTDispatcher.getInstance().dispatch(info);
		//写回数据
		try {
			byte[] data = new byte[36];
			Tools.int2byte(36, data, 0);
			Tools.int2byte(Constants.SUBMIT_RES, data, 4);
			Tools.int2byte(ack.getStatus(), data, 8);
			System.arraycopy(submitReq, 8, data, 12, 4);
			if (ack.getStatus() == 0) {
				byte[] msgId = new byte[8];
				if (ack.msgId != null)
					msgId = ack.msgId.getBytes();
				System.arraycopy(msgId, 0, data, 16, msgId.length);
			}
			out.write(data);
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -