最近项目涉及到与C的通讯,目的是转发一下信息,Java这边使用的时监听Socket的接口,只要给C提供IP和端口 就行了。

已知Socket的编程有 TCP和UDP协议,据说UDP更快一点 这里使用的UDP编程

1.创建一个服务类PushPrinterServer

  

import com.util.GetByteEncode;
import com.util.HttpClientUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;

import static com.constants.PrinterSocketConstants.PRINTER_URL;

public class PushPrinterServer extends Thread {
    private static final int PORT=9002;//监听的端口号
    private static final Logger LOGGER = LoggerFactory.getLogger(PushPrinterServer.class);
    private DatagramSocket datagramSocket=null;

    public PushPrinterServer(DatagramSocket datagramSocket) {
        if (datagramSocket==null){
            try {
                LOGGER.info("开启推送打印服务器端口"+PORT);
                this.datagramSocket = new DatagramSocket(PORT);
            }catch (Exception e){
                LOGGER.error("开启socket推送打印服务出错");
                e.printStackTrace();
            }
        }
    }
    @Override
    public void run() {
        try {
            while (!this.isInterrupted()) {
//                // 一旦有堵塞, 则表示服务器与客户端获得了连接
                byte[] receiveData = new byte[1024];
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                datagramSocket.receive(receivePacket);// 在接收到信息之前,一直保持阻塞状态

                String encoding = GetByteEncode.getEncoding(receiveData);//编码判断
                System.out.println("字符编码是:"+encoding);

                ByteBuffer byteBuffer = ByteBuffer.wrap(receiveData);
                CharBuffer gb18030 = Charset.forName("GB18030").decode(byteBuffer);
                ByteBuffer utf8 = Charset.forName("UTF8").encode(gb18030);
                String data= new String(utf8.array());
                LOGGER.info("客户端发送消息:"+data);
                try {
                    if(receiveData!=null){
                        HttpClientUtil.requestHttpPost(data,PRINTER_URL);
                        LOGGER.info("已向管理平台发送请求...");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    LOGGER.info("向管理平台发送请求失败");
                }

            }
        } catch (Exception e) {
            LOGGER.error("推送打印异常: " + e.getMessage());
        }
    }

    public void closeSocketServer(){
        if(null!=datagramSocket && !datagramSocket.isClosed())
        {
            LOGGER.info("关闭推送打印服务器");
            datagramSocket.close();
        }
    }
}
-----------------------------------------------------------------------------------------------
receiveData 是监听接口收到是字节组的源数据,由于发过来的中文乱码,但一直处理不了,所有这里先查出源数据的编码格式,再进行处理,data是处理
完的数据,然后转发一下就好了。

2.创建一个监听类PushPrinterSocketServiceLoader
网上许多写的多写在main方法里面,但是真实的项目怎么办呢,要让它项目已启动就开启线程监听,创建监听类
import com.service.PushPrinterServer;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class PushPrinterSocketServiceLoader implements ServletContextListener {
    //socket server 线程
    private PushPrinterServer pushPrinterServer;
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        if(null==pushPrinterServer)
        {
            //新建线程类
            pushPrinterServer=new PushPrinterServer(null);
            //启动线程
            pushPrinterServer.start();
        }
    }
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        if(null!=pushPrinterServer && !pushPrinterServer.isInterrupted())
        {
            System.out.println("推送打印服务器关闭");
            pushPrinterServer.closeSocketServer();
            pushPrinterServer.interrupt();
        }
    }
}
3.在web.xml添加配置
<listener>
    <listener-class>com.listener.PushPrinterSocketServiceLoader</listener-class>
</listener>