最近项目涉及到与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>