如何使用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

原文地址:https://www.cnblogs.com/lyhero11/p/4836408.html