package com.evideostb.billsystem.socket;
import com.evideostb.billsystem.properties.DbInitReader;
import net.sf.json.JSONObject;
import java.io.*;
import java.net.*;
import java.util.Map;
/**
* 网络支付TCP请求
* Created by zhangchuanzhao on 2015-12-02 17:26.
*/
public class NetpaySocket {
private static final String IP_ADDR = DbInitReader.getInstance().getNetpayIPAddress();//服务器地址
private static final int PORT = DbInitReader.getInstance().getNetpayIPPort();//服务器端口号
//发送到服务端的内容
private static byte[] buf = null;
@SuppressWarnings("unchecked")
public static Map<String,Object> connectTcp(String params) throws Exception{
params = new String(params.getBytes("utf-8"),"gbk");
setContent(params);
System.out.println("客户端启动...");
//创建一个流套接字并将其连接到指定主机上的指定端口号
Socket socket = new Socket(IP_ADDR, PORT);
//设置超时时间
socket.setSoTimeout(60000);
OutputStream os = socket.getOutputStream();
//需要发送的内容
os.write(buf);
DataOutputStream out = new DataOutputStream(os);
//发送
out.flush();
String str = bytesToString(buf,0,params.getBytes("gbk").length + 20);
System.out.println("客户端请求数据:"+str);
InputStream is = socket.getInputStream();
DataInputStream in = new DataInputStream(is);
//读取服务端返回内容
byte[] clientbyte = readBytes(in);
//截取包体
String content = bytesToString(clientbyte,20,clientbyte.length);
System.out.println("服务器端返回过来的是: " + content);
socket.close();
JSONObject receiveJson = JSONObject.fromObject(content);
return (Map<String,Object>)receiveJson;
}
/**
* 设置发送的内容
* @param params
* @throws IOException
*/
private static void setContent(String params) throws IOException {
//发送到服务端的内容长度是包头和包体长度总和
buf = new byte[params.getBytes().length + 20];
//标识
byte[] flag = new byte[2];
flag[0] = 'E';
flag[1] = 'V';
System.arraycopy(flag, 0, buf, 0, flag.length);
//版本
byte[] ver = new byte[2];
ver[0] = '1';
ver[1] = '0';
System.arraycopy(ver, 0, buf, 2, ver.length);
//正文长度,4字节
int datalen = params.getBytes("gbk").length;
byte[] datalenByte = intToByte(datalen);
System.arraycopy(datalenByte, 0, buf, 4 , datalenByte.length);
//预留,4字节
byte[] reserved = new byte[4];
System.arraycopy(reserved, 0, buf, 8, reserved.length);
//密钥,对正文内容加密
byte[] key = new byte[8];
System.arraycopy(key, 0, buf, 12, key.length);
//设置需要发送的内容,包头和包体
System.arraycopy(params.getBytes("gbk"), 0, buf, 20, datalen);
}
/**
* 读取内容
* @param in
* @return
* @throws IOException
*/
private static byte[] readBytes(InputStream in) throws IOException {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int read = 1024;
int readSize = 1024;
while (read == readSize) {
read = in.read(buffer, 0, readSize);
bo.write(buffer, 0, read);
}
return bo.toByteArray();
}
/**
* 将int转为低字节在前,高字节在后的byte数组
*/
private static byte[] intToByte(int n) {
byte[] bLocalArr = new byte[4];
for (int i = 0; (i < 4) && (i < 4); i++) {
bLocalArr[i] = (byte) (n >> 8 * i & 0xFF);
}
return bLocalArr;
}
/**
* 将字节数组转化为string
*/
private static String bytesToString(byte [] bytes,int start,int end) throws Exception{
String str = "";
if(bytes.length<end){
return str;
}
byte [] bs = new byte[end-start];
for(int i = start;i<end;i++){
bs[i-start] = bytes[i];
}
str = new String(bs,"utf-8");
return str;
}
public static void main(String[] args) {
JSONObject json = new JSONObject();
json.put("cmd_id","AP001");
json.put("subject","subject");
json.put("out_trade_no","JZD20141124001");
json.put("total_fee","100.00");
try {
Map<String,Object> result = NetpaySocket.connectTcp(json.toString());
System.out.println(result.get("cmd_id"));
}catch (Exception e){
e.printStackTrace();
}
}
}