zoukankan      html  css  js  c++  java
  • 如何使用socket进行java网络编程(一)

         笔者进来遇到一个项目,一家公司的系统需要在完成自身业务逻辑的同时,接入到某银行的核心系统(这里准确说应该是前置机)进行一系列的账务处理,然后再将账务处理结果返回给该公司系统。

         网络通信采用TCP协议。

     由于公司方和银行的TCP协议报文有所不同,故整个项目的方案是在两者之间架设一个转发机(由银行方提供),用来进行协议报文的转换。

    分析一下,整个系统的交易分为一下几个部分:

    1、需要在转发机上建立一个socket服务器程序,用来监听来自于公司方的socket请求。

    2、收到该请求后,分配一个线程,执行该请求逻辑,包括:

         (1)、接收公司方的协议报文,转换为银行前置机报文

         (2)、将转换后的报文发送给银行前置机

         (3)、银行前置机接收转发机报文并执行账务处理,而后将结果发送给转发机

         (4)、转发机读取前置机返回的报文,转换为公司方协议报文,并发送给公司方

         (5)、公司方收到转发机返回的结果

    以上为了简化,我们采用阻塞式IO设计,即在一个过程中按顺序执行上述(1)到(5)的步骤。

    另外,同样为了简化我们的程序设计,并不在转发机的socket服务器程序上采用线程池设计。

    package com.zjjs.server;
    
    import java.io.IOException;
    import java.net.BindException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    import org.apache.log4j.Logger;
    /**
     * create by linyang 2015-09-18
     * 套接字服务器
     * 监听来自第三方的请求,对于每个请求启动一个处理线程
     * **/
    public class ZjjsTransServer {
        private static final int _PORT_ = 9091;
        private static Logger logger = Logger.getLogger(ZjjsTransServer.class);
    
        public static void main(String args[]) {
            try {
                ServerSocket server = new ServerSocket(_PORT_);
                logger.info("socket服务器启动,端口[" + _PORT_ + "]...");
                while (true) {
                    Socket nextClient = server.accept();
                    logger.info("接收到来自:" + nextClient.getInetAddress() + "["
                            + nextClient.getPort() + "]的请求/n" + "socket hashcode["
                            + nextClient.hashCode() + "]");
                    SocketHandler handler = new SocketHandler(nextClient);
                    Thread t = new Thread(handler);
                    t.start();
                }
            } catch (BindException be) {
                logger.error("socket服务器端口冲突" + _PORT_);
            } catch (IOException ioe) {
                logger.error("I/O error" + ioe);
            }
        }
    }
    package com.zjjs.server;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.Socket;
    
    import org.apache.log4j.Logger;
    
    import com.zjjs.trans.Trans;
    import com.zjjs.trans.ZjjsTrans;
    /**
     * create by linyang 2015-09-18
     * 套接字请求处理线程
     * 完成 接收第三方--->发送前置机--->接收前置机--->发送第三方 等步奏
     * **/
    public class SocketHandler implements Runnable {
    
        private Socket socket = null;
        private Socket frontSocket = null;
        private static Logger logger = Logger.getLogger(SocketHandler.class);
    
        public SocketHandler(Socket socket) {
            super();
            this.socket = socket;
        }
    
        @Override
        public void run() {
            String datagram = null;
            String send2frontDatagram = null;
            ZjjsTrans transProcesser = null;
            String transCode = "";
            Trans trans = null;
            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        this.socket.getInputStream()));
                datagram = reader.readLine();
                logger.info("接收到第三方报文" + datagram);
                transCode = datagram.substring(4, 8);
                try {
                    try {
                        trans = (Trans) Class.forName("com.zjjs.trans.Trans" + transCode)
                                .newInstance();
                    } catch (InstantiationException inse) {
                        inse.printStackTrace();
                        logger.error("实例化交易失败,交易类型" + "Trans" + transCode + ", "
                                + inse);
                    } catch (IllegalAccessException ille) {
                        ille.printStackTrace();
                        logger.error("实例化交易失败IllegalAccessException,交易类型" + "Trans"
                                + transCode + ", " + ille);
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                    logger.error("未找到交易类型" + "com.zjjs.trans.Trans" + transCode + ", " + e);
                }
    
                transProcesser = new ZjjsTrans(trans);
                logger.info("解析收到第三方报文开始...");
                transProcesser.parserDatagramReceive(datagram);
                logger.info("解析收到第三方报文结束");
                logger.info("开始生成转发到前置机报文...");
                send2frontDatagram = transProcesser.toFrontServerDatagram();
                logger.info("结束生成转发到前置机报文,报文内容[" + send2frontDatagram + "]");
    
                frontSocket = new Socket("158.222.65.155", 8008);
                logger.info("开始向前置机发送报文...");
                PrintWriter  printer = new PrintWriter (new OutputStreamWriter(frontSocket.getOutputStream()));
                /*
                OutputStreamWriter writer = new OutputStreamWriter(
                        frontSocket.getOutputStream()); */
                printer.println(send2frontDatagram);
                printer.flush();
                //printer.close();
                logger.info("向前置机发送报文结束");
                
                logger.info("开始接收前置机返回报文...");
                BufferedReader frontreader = new BufferedReader(new InputStreamReader(frontSocket.getInputStream()));
                String frontReturnDatagram = frontreader.readLine();
    printer.close(); logger.info(
    "前置机返回报文[" + frontReturnDatagram + "]"); logger.info("接收前置机返回报文结束"); logger.info("开始将前置机返回报文转换为返回给第三方报文..."); String toThirdDatagram = transProcesser.toThirdServerDatagram(frontReturnDatagram); logger.info("转换后返回第三方报文[" + toThirdDatagram + "]"); logger.info("将前置机返回报文转换为返回给第三方报文结束"); logger.info("开始向第三方返回结果报文..."); /* Socket toThirdSocket = new Socket("xxxxx", 8008); PrintWriter thirdPrinter = new PrintWriter (new OutputStreamWriter(toThirdSocket.getOutputStream())); thirdPrinter.println(toThirdDatagram); thirdPrinter.flush(); thirdPrinter.close(); */ logger.info("向第三方返回结果报文结束"); } catch (IOException ioe) { logger.error("I/O error:" + ioe); } } }

    2015-11-6 补充,上述程序存在一定隐患,http://www.cnblogs.com/lyhero11/p/4943433.html

  • 相关阅读:
    redis配置文件参数说明及命令操作
    在Window 下安装Redis数据库
    eclipse怎样在线安装hibernate tools插件并使用
    eclipse如何优化构建的速度(Building)
    java实现敏感词过滤(DFA算法)
    eclipse编码格式设置
    Jquery Ajax简单封装(集中错误、请求loading处理)
    Vue简单封装axios—解决post请求后端接收不到参数问题
    vue项目实现记住密码功能
    vue路由的两种模式配置以及history模式下面后端如何配置
  • 原文地址:https://www.cnblogs.com/lyhero11/p/4836408.html
Copyright © 2011-2022 走看看