📄 spsmsservice2.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 + -