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. web开发中经常使用的js

    将自己在web开发中经经常使用到的一些JS总结一下. 1.改动标签和表单的值 改动标签的值: var customer = document.getElementById("custm&qu ...

  2. linux服务器宕机分析/性能瓶颈分析

    linux服务器宕机分析/性能瓶颈分析   服务器宕机原因很多,资源不足.应用.硬件.系统内核bug等,以下一个小例子 服务器宕机了,首先得知道服务器宕机的时间点,然后分析日志查找原因 1.last ...

  3. Eclipse 创建 XML 文件

    Eclipse 创建 XML 文件 打开新建 XML 文件向导 你可以使用新建 XML 文件向导来创建 XML 文件.打开向导的方式有: 点击 File 菜单并选择 New > Other 点击 ...

  4. Unity3D学习笔记——初级知识

    一:Unity欢迎窗口对于初学者来说有很多有价值的信息,值得用户关注,以下将简要介绍这个窗口中的相关内容: 1.Video Tutorials: 提供unity相关的教程 ,包括用户手册 .组件手册以 ...

  5. Unicode与UTF-8互转(c语言和lua语言)

    1. 基础 1.1 ASCII码 我们知道, 在计算机内部, 全部的信息终于都表示为一个二进制的字符串. 每个二进制 位(bit)有0和1两种状态, 因此八个二进制位就能够组合出 256种状态, 这被 ...

  6. Android程序执行shell脚本

    在做Android应用时,经常需要执行shell脚本,以快速实现某些功能: 在Android应用程序中执行shell脚本可以省去一大堆繁琐的代码,还可以避免不必要的错误: 比如:拷贝文件夹时,可以执行 ...

  7. ul和li弄的图片列表

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 关于js的当前日期的格式化,和两个日期之间的相减的天数

    function getFormatYMD(timesamp){ var date = new Date(timesamp); Y = date.getFullYear() + '-'; M = (d ...

  9. Linux 常用命令缩写及对应的

    0.项目名: Linux -- LINUs' uniX (开个玩笑不是这样的,别当真) GNU -- Gnu is Not Unix1.目录名: /boot:顾名思义 /root :同上 /run:同 ...

  10. Introduction to Mathematical Thinking - Week 2

    基本数学概念 real number(实数):是有理数和无理数的总称 有理数:可以表达为两个整数比的数(a/b, b!=0) 无理数是指除有理数以外的实数 imply -- 推导出 不需要 A 能推导 ...