package com.pab.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* 平安银行
* @author jian.zhou
*/
public class PabUtil {
/** 不允许实例 */
private PabUtil() {
super();
}

private final static Logger log = LoggerFactory.getLogger(PabUtil.class);

private static final int[] FIELD_LENGTH_INDEX = new int[] { // 用来计算各个字段的在报文头中的长度和位置
1, 7, 9, 11, 31, 41, 47, 52, 54, 62, 68, 88, 94, 194, 195, 198, 199, 200, 212, 222, 223 };

private static int[] FIELD_LENGTH = new int[FIELD_LENGTH_INDEX.length]; // 纪录各个字段的字节表示在数组中的起始位置,最后一位是补位-为方便解析而添加

static {
for (int i = 0; i < FIELD_LENGTH_INDEX.length; i++) {
FIELD_LENGTH[i] = FIELD_LENGTH_INDEX[i] - 1;
}
}

/**
* 截取字节
* @param src
* @param begin
* @param end
* @return
*/
public static byte[] subBytes(byte[] src, int begin, int end) {
int len = end - begin;
byte[] bs = new byte[len];
for (int i = begin; i < begin + len; i++)
bs[i - begin] = src[i];
return bs;
}

/**
* 发送报文
* @param msg 报文
* @return String[] = backArray[0]状态 = succ, fail, backArray[1] = 返回的报文
*/
public static String[] sendPacket(String msg, Properties prop) {
log.info("PAB 110001 SEND PACKET IS:{}", msg);
Socket socket = null;
BufferedInputStream bi = null;
BufferedOutputStream bo = null;
InputStream in = null;
String backMsg = "";
String[] backStr = new String[2];
String ip = prop.getProperty("merCustomIp");
int port = Integer.parseInt(prop.getProperty("pfxPassword"));
try {
// 客户端socket指定服务器的地址和端口号
socket = new Socket(ip, port);
socket.setSoTimeout(30000);
log.info("{}", socket);

OutputStream ops = socket.getOutputStream();
bo = new BufferedOutputStream(ops);
bo.write(msg.getBytes(PabContants.PINGAN_CODE_UTF8));
bo.flush();

in = socket.getInputStream();
bi = new BufferedInputStream(in);
byte[] hb = new byte[PabContants.PACKET_HEAD_LENGTH];// 读取固定报文头 长度为222
bi.read(hb, 0, PabContants.PACKET_HEAD_LENGTH);

log.info("PAB 110001 BACK PACKET HEAD IS:{}", new String(hb, PabContants.PINGAN_CODE_UTF8));

// 截取报文头 长度 222 位z
String[] packetHead = new String[FIELD_LENGTH_INDEX.length - 1];// 报文数组
int j = 0;
for (int i = 1; i < FIELD_LENGTH.length; i++) {
int start = FIELD_LENGTH[i - 1];
int end = FIELD_LENGTH[i];
byte[] b = subBytes(hb, start, end);
packetHead[j] = new String(b, PabContants.PINGAN_CODE_UTF8);
j++;
}
log.info("pakcetHead {}", Arrays.toString(packetHead));

// 根据开发文档 报文头的返回码为000000,表示后续存在xml报文体
if ("000000".equals(packetHead[11])) {
log.info("---start receive packet body----");

int parcketLength = Integer.parseInt(packetHead[4]);
byte[] backmsg = new byte[parcketLength];
int cnt = 0;
int iLen = 0;
while (cnt < (parcketLength)) {
iLen = bi.read(backmsg, cnt, parcketLength);
cnt += iLen;
}

backMsg = new String(backmsg, PabContants.PINGAN_CODE_UTF8);
backStr[0] = "succ";
backStr[1] = backMsg;
log.info("PAB 110001 BACK PACKET HEAD BODY IS:" + backStr[1]);
log.info("---end receive packet body----");
} else if ("YQ9996".equals(packetHead[11])) {
backStr[0] = "confirm";
backStr[1] = packetHead[11] + ":" + packetHead[12];
} else {
backStr[0] = "fail";
backStr[1] = packetHead[11] + ":" + packetHead[12];
log.info("trans error--- packetBody is not, backcode:" + packetHead[11] + ":" + packetHead[12].trim());
}

} catch (Exception e) {
log.error("{}", e);
} finally {
try {
if (bi != null) {
bi.close();
}
if (bo != null) {
bo.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
log.error("", e);
}
}
return backStr;
}

/**
* 判断是否为空
* @param str
* @return
*/
public static String isNull(String str) {
if (str == null) return "";
else return str;
}
}

Socket 例子的更多相关文章

  1. 阻塞式socket例子学习

    /************************************************************************* > File Name: Win_Serve ...

  2. python3.* socket例子

    On Server: # -*- coding: utf-8 -*-#this is the server import socketif "__main__" == __name ...

  3. 简单的SOCKET例子

    定义实例socket.socket(),如果括号里不写参数,默认为IPV4+TCP 我们猜测客户端的完整代码如下: 同样我们猜测服务端的代码如下: 实际上运行客户端代码: 说明在py3里,网络编程发送 ...

  4. 网络编程 - 简单的socket例子

    1.客户端 #客户端import socketclient=socket.socket() #生成socket连接对象client.connect(("localhost",696 ...

  5. 基于TCP的socket通信过程及例子

    Socket也叫套接字,用来实现网络通讯,通过调用系统提供的API,可以和远程的机子传输数据.Socket有很多种协议,而这篇文章主要讨论TCP部分的内容,也就是说后面说的内容主要是指TCP Sock ...

  6. coco2dx服务器简单例子

    实现的单个socket例子,了解socket原理. 先创建一个win32的项目(命令行的),作为服务端 // SocketServer.cpp : 定义控制台应用程序的入口点.// #include ...

  7. .NET平台下几种SOCKET模型的简要性能供参考

    转载自:http://www.cnblogs.com/asilas/archive/2006/01/05/311309.html .NET平台下几种SOCKET模型的简要性能供参考 这个内容在cnbl ...

  8. Python Socket通信原理

    [Python之旅]第五篇(一):Python Socket通信原理   python Socket 通信理论 socket例子 摘要:  只要和网络服务涉及的,就离不开Socket以及Socket编 ...

  9. Python Socket单线程+阻塞模式

    Python之旅]第五篇(二):Python Socket单线程+阻塞模式 python Socket单线程 Socket阻塞模式 串行发送 摘要:  前面第五篇(一)中的一个Socket例子其实就是 ...

随机推荐

  1. Codeforces 460E Roland and Rose(暴力)

    题目链接:Codeforces 460E Roland and Rose 题目大意:在以原点为圆心,半径为R的局域内选择N个整数点,使得N个点中两两距离的平方和最大. 解题思路:R最大为30.那么事实 ...

  2. 2017-5-14 湘潭市赛 Partial Sum 给n个数,每次操作选择一个L,一个R,表示区间左右端点,该操作产生的贡献为[L+1,R]的和的绝对值-C。 0<=L<R<=n; 如果选过L,R这两个位置,那么以后选择的L,R都不可以再选择这两个位置。最多操作m次,求可以获得的 最大贡献和。

    Partial Sum Accepted : Submit : Time Limit : MS Memory Limit : KB Partial Sum Bobo has a integer seq ...

  3. Spring MVC的@ResponseBody回来JSON串

    1 406错误 <mvc:annotation-driven />不用动,请求的时候URL的文件扩展名应为json @ResponseBody会根据扩展名,或者Header,或者Param ...

  4. 第一百八十四节,jQuery-UI,验证注册表单

    jQuery-UI,验证注册表单 html <form id="reg" action="123.html" title="会员注册" ...

  5. css 定位标签设置格式

    td a {      color: #3c8dbc; } td a:hover {      color: #00bdd8; } 上例即为定位td下的a标签.即用来给表格中的链接,未访问时和hove ...

  6. 在NodeJS中使用流程控制工具Async

    本文介绍一款流程控制工具async,在编写接口或者编写测试用例的过程中总是会用到它. 由于nodejs是异步编程模型,有一些在同步编程中很容易做到的事情,现在却变得很麻烦.Async的流程控制就是为了 ...

  7. 如何学习TP框架

    1.学习访问方法 2.控制器的写法 3.视图的写法 4.模型的写法 5.扩展类的用法 6.扩展插件的用法

  8. Redis 在windows中启动

    redis-server.exe redis.windows.conf 或 redis-server.exe redis.conf

  9. VIM快速使用

    1.VIM键盘图[转] 2.vi复制多行文本的方法 2.1 方法1:光标放到第6行, 输入:2yy 光标放到第9行, 输入:p 此方法适合复制少量行文本的情况,复制第6行(包括)下面的2行数据,放到第 ...

  10. Android--去除EditText边框,加入下划线

    <span style="font-family: Arial, Helvetica, sans-serif;"><?xml version="1.0& ...