最近項目涉及到與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>