//客户端
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
public class Client {
public static Socket socket;
public static String IP = "127.0.0.1";
public static int port = 55555;
public static DataInputStream in;
public static DataOutputStream out;
//创建指定地址的Socket连接
public static Socket getSocketInstance(){
try {
socket=new Socket(IP,port);
socket.setKeepAlive(true);
socket.setSoTimeout(10000);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return socket;
}
//发送短消息
public static void sendShortMsg(String msg,String phoneNumber) throws IOException{
int seq=MsgUtils.getSequence();
try {
byte[] msgByte=msg.getBytes("gb2312");
CMPP_SUBMIT submit=new CMPP_SUBMIT();
submit.setTotalLength(159+msgByte.length);
submit.setCommandId(0x00000004);
submit.setSequenceId(seq);
submit.setMsg_src("账户:18983845949");
submit.setSrc_Id("通道号:5");
submit.setDest_terminal_Id(phoneNumber);
submit.setMsg_Length((byte)msgByte.length);
submit.setMsg_Content(msgByte);
List
dataList.add(submit.toByteArray());
if(out!=null&&null!=dataList){
for(byte[]data:dataList){
out.write(data);
out.flush();
System.out.println("submit数据发送完成");
}
}
// in=new DataInputStream(socket.getInputStream());
// int len=in.readInt();
// List
// if(null!=in&&0!=len){
// byte[] data=new byte[len-4];
// in.read(data);
// getData.add(data);
// for(byte[] returnData:getData){
// Message_Header header=new Message_Header(returnData);
// switch(header.getCommandId()){
// case 0x80000004:
// CMPP_SUBMIT_RESP submitResp=new CMPP_SUBMIT_RESP(returnData);
// System.out.println("submitresp状态值"+submitResp.getResult());
// System.out.println("submitresp流水号值"+submitResp.getMsg_Id());
// }
// }
// }
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void connectISMG() throws IOException{
System.out.println("正在连接到服务器" + IP);
CMPP_CONNECT connect=new CMPP_CONNECT();
connect.setTotalLength(12+6+16+1+4);
connect.setCommandId(0x00000001);
connect.setSequenceId(MsgUtils.getSequence());
connect.setSourceAddr("18983845555");
String timestamp=MsgUtils.getTimestamp();
connect.setAuthenticatorSource(MsgUtils.getAuthenticatorSource("18983845555", "123456", timestamp));
connect.setTimestamp(Integer.parseInt(timestamp));
connect.setVersion((byte)0x20);
List
dataList.add(connect.toByteArray());
out = new DataOutputStream(socket.getOutputStream());
if(out!=null&&null!=dataList){
for(byte[] data : dataList){
out.write(data);
out.flush();
System.out.println("connect数据发送完成");
}
}
out.write("Hello,Server".getBytes());
System.out.println("Hello,Server问候语 发送完成");
// in = new DataInputStream(socket.getInputStream());
// int len = in.readInt();
// List
// if(null!=in&&0!=len){
// byte[] data=new byte[len-4];
// in.read(data);
// getData.add(data);
// for(byte[] returnData:getData){
// Message_Header header=new Message_Header(returnData);
// switch(header.getCommandId()){
// case 0x80000001:
// CMPP_CONNECT_RESP connectResp=new CMPP_CONNECT_RESP(returnData);
// System.out.println("CMPP初始化链接状态值"+connectResp.getStatus());
// }
// }
// }
}
public static void main(String[] args) throws IOException {
Socket socket = getSocketInstance();
// OutputStream outputStream = null;
// InputStream inputStream = null;
// try {
// outputStream = socket.getOutputStream();
// inputStream = socket.getInputStream();
// out = new DataOutputStream(outputStream);
// out.write("Hello,Server".getBytes());
// out.flush();
// System.out.println("数据发送成功");
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// outputStream.close();
// inputStream.close();
connectISMG();
sendShortMsg("你好,我想发送一条短消息","18723134500");
// out.close();
// in.close();
socket.close();
}
}
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class CMPP_CONNECT extends Message_Header{
private String sourceAddr;//
private byte[] authenticatorSource;//
private byte version;//
private int timestamp;//
public byte[] toByteArray(){
ByteArrayOutputStream bous=new ByteArrayOutputStream();
DataOutputStream dous=new DataOutputStream(bous);
try {
dous.writeInt(this.getTotalLength());
dous.writeInt(this.getCommandId());
dous.writeInt(this.getSequenceId());
MsgUtils.writeString(dous,this.sourceAddr,6);
dous.write(authenticatorSource);
dous.writeByte(version);
dous.writeInt(timestamp);
dous.close();
} catch (IOException e) {
System.out.print("封装链接二进制数组失败。");
}
return bous.toByteArray();
}
public String getSourceAddr() {
return sourceAddr;
}
public void setSourceAddr(String sourceAddr) {
this.sourceAddr = sourceAddr;
}
public byte[] getAuthenticatorSource() {
return authenticatorSource;
}
public void setAuthenticatorSource(byte[] authenticatorSource) {
this.authenticatorSource = authenticatorSource;
}
public byte getVersion() {
return version;
}
public void setVersion(byte version) {
this.version = version;
}
public int getTimestamp() {
return timestamp;
}
public void setTimestamp(int timestamp) {
this.timestamp = timestamp;
}
}
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
public class CMPP_CONNECT_RESP extends Message_Header {
private int status;//响应状态状态 0:正确 1:消息结构错 2:非法源地址 3:认证错 4:版本太高 5~ :其他错误
private String statusStr;//响应状态状态 0:正确 1:消息结构错 2:非法源地址 3:认证错 4:版本太高 5~ :其他错误
private byte[] authenticatorISMG;// ISMG认证码,用于鉴别ISMG。 其值通过单向MD5 hash计算得出,表示如下: AuthenticatorISMG =MD5(Status+AuthenticatorSource+shared secret),Shared secret 由中国移动与源地址实体事先商定,AuthenticatorSource为源地址实体发送给ISMG的对应消息CMPP_Connect中的值。 认证出错时,此项为空。
private byte version;// 服务器支持的最高版本号,对于3.0的版本,高4bit为3,低4位为0
public CMPP_CONNECT_RESP(byte[] data){
if(data.length==8+1+16+1){
ByteArrayInputStream bins=new ByteArrayInputStream(data);
DataInputStream dins=new DataInputStream(bins);
try {
this.setTotalLength(data.length + 4);
this.setCommandId(dins.readInt());
this.setSequenceId(dins.readInt());
this.setStatus(dins.readByte());
byte[] aiByte=new byte[16];
dins.read(aiByte);
this.authenticatorISMG=aiByte;
this.version=dins.readByte();
dins.close();
bins.close();
} catch (IOException e){}
}else{
System.out.println("链接至IMSP,解析数据包出错,包长度不一致。长度为:"+data.length);
}
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
switch(status){
case 0 : statusStr="正确";break;
case 1 : statusStr="消息结构错";break;
case 2 : statusStr="非法源地址";break;
case 3 : statusStr="认证错";break;
case 4 : statusStr="版本太高";break;
case 5 : statusStr="其他错误";break;
default:statusStr=status+":未知";break;
}
}
}
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class Message_Header {
private int totalLength;//Unsigned Integer
private int commandId;//Unsigned Integer
private int sequenceId;//Unsigned Integer
public byte[] toByteArray(){
ByteArrayOutputStream bous=new ByteArrayOutputStream();
DataOutputStream dous=new DataOutputStream(bous);
try {
dous.writeInt(this.getTotalLength());
dous.writeInt(this.getCommandId());
dous.writeInt(this.getSequenceId());
dous.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("封装CMPP消息头二进制数组失败。");
}
return bous.toByteArray();
}
public Message_Header(byte[] data){
ByteArrayInputStream bins=new ByteArrayInputStream(data);
DataInputStream dins=new DataInputStream(bins);
try {
this.setTotalLength(data.length+4);
this.setCommandId(dins.readInt());
this.setSequenceId(dins.readInt());
dins.close();
bins.close();
} catch (IOException e){}
}
public Message_Header(){
super();
}
public int getTotalLength() {
return totalLength;
}
public void setTotalLength(int totalLength) {
this.totalLength = totalLength;
}
public int getCommandId() {
return commandId;
}
public void setCommandId(int commandId) {
this.commandId = commandId;
}
public int getSequenceId() {
return sequenceId;
}
public void setSequenceId(int sequenceId) {
this.sequenceId = sequenceId;
}
}
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 短信接口辅助工具类
* @author 张科伟
* 2011-08-22 15:03
*/
public class MsgUtils {
private static int sequenceId=0;//序列编号
//序列自增
public synchronized static int getSequence(){
++sequenceId;
if(sequenceId>255){
sequenceId=0;
}
return sequenceId;
}
//时间戳明文
public static String getTimestamp(){
DateFormat format=new SimpleDateFormat("MMddhhmmss");
return format.format(new Date());
}
//用于鉴别源地址,MD5
public static byte[] getAuthenticatorSource(String spId,String secret, String timestamp){
try {
MessageDigest md5=MessageDigest.getInstance("MD5");
byte[] data=(spId+"\0\0\0\0\0\0\0\0\0"+secret+timestamp).getBytes();
md5.update(data);
return md5.digest();
} catch (NoSuchAlgorithmException e) {
//log.error("SP链接到ISMG拼接AuthenticatorSource失败:"+e.getMessage());
return null;
}
}
//向流中写入指定长度的字符串,不足补零
public static void writeString(DataOutputStream dous,String s,int len){
try {
byte[] data=s.getBytes("gb2312");
if(data.length>len){
//log.error("向流中写入的字符串超长!要写"+len+" 字符串是:"+s);
}
int srcLen=data.length;
dous.write(data);
while(srcLen
srcLen++;
}
} catch (IOException e) {
//log.error("向流中写入指定字节长度的字符串失败:"+e.getMessage());
}
}
//从流中读取字符串
public static String readString(java.io.DataInputStream ins,int len){
byte[] b=new byte[len];
try {
ins.read(b);
String s=new String(b);
s=s.trim();
return s;
} catch (IOException e) {
return "";
}
}
//截取字段
public static byte[] getMsgBytes(byte[] msg,int start,int end){
byte[] msgByte=new byte[end-start];
int j=0;
for(int i=start;i
j++;
}
return msgByte;
}
/**
* UCS2解码
*
* @param src
* UCS2 源串
* @return 解码后的UTF-16BE字符串
*/
public static String DecodeUCS2(String src) {
byte[] bytes = new byte[src.length()/2];
for (int i = 0; i < src.length(); i += 2) {
bytes[i/2]=(byte)(Integer.parseInt(src.substring(i, i + 2), 16));
}
String reValue = "";
try {
reValue = new String(bytes, "UTF-16BE");
} catch (UnsupportedEncodingException e) {
reValue="";
}
return reValue;
}
/**
* UCS2编码
*
* @param src
* UTF-16BE编码的源串
* @return 编码后的UCS2串
*/
public static String EncodeUCS2(String src) {
byte[] bytes;
try {
bytes = src.getBytes("UTF-16BE");
} catch (UnsupportedEncodingException e) {
bytes=new byte[0];
}
StringBuffer reValue = new StringBuffer();
StringBuffer tem = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
tem.delete(0, tem.length());
tem.append(Integer.toHexString(bytes[i] & 0xFF));
if(tem.length()==1){
tem.insert(0,'0');
}
reValue.append(tem);
}
return reValue.toString().toUpperCase();
}
}
//服务器
import java.awt.List;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
public static void main(String[] args) {
try {
//创建一个ServerSocket并绑定端口号
ServerSocket serverSocket = new ServerSocket(55555);
//调用accept()方法进行监听
System.out.println("正在等待客户端连接......");
Socket socket = serverSocket.accept();
System.out.println("客户端连接成功");
//获取输入流读取客户端信息
InputStream inputStream = socket.getInputStream();
InputStreamReader isr= new InputStreamReader(inputStream,"gb2312");//将字节流转换为字符流
BufferedReader br= new BufferedReader(isr);//为输入流添加缓冲
String info = null;
while((info=br.readLine())!=null) {
System.out.println("客户端: " + info);
}
socket.shutdownInput(); //关闭输入流
OutputStream outputStream = socket.getOutputStream();
outputStream.write("收到消息".getBytes());
outputStream.flush();
//释放资源
inputStream.close();
outputStream.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}