package net.fs.client; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import net.fs.rudp.Route; import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.HashMap; public class PortMapManager { MapClient mapClient; ArrayList<MapRule> mapList = new ArrayList<>(); HashMap<Integer, MapRule> mapRuleTable = new HashMap<>(); String configFilePath = "port_map.json"; PortMapManager(MapClient mapClient) { this.mapClient = mapClient; //listenPort(); loadMapRule(); } public static String readFileUtf8(String path) throws Exception { String str = null; FileInputStream fis = null; DataInputStream dis = null; try { File file = new File(path); int length = (int) file.length(); byte[] data = new byte[length]; fis = new FileInputStream(file); dis = new DataInputStream(fis); dis.readFully(data); str = new String(data, "utf-8"); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } if (dis != null) { try { dis.close(); } catch (IOException e) { e.printStackTrace(); } } } return str; } void addMapRule(MapRule mapRule) throws Exception { if (getMapRule(mapRule.name) != null) { throw new Exception("映射 " + mapRule.name + " 已存在,请修改名称!"); } ServerSocket serverSocket; try { serverSocket = new ServerSocket(mapRule.getListen_port()); listen(serverSocket); mapList.add(mapRule); mapRuleTable.put(mapRule.listen_port, mapRule); saveMapRule(); } catch (IOException e2) { //e2.printStackTrace(); throw new Exception("端口 " + mapRule.getListen_port() + " 已经被占用!"); } } void removeMapRule(String name) { MapRule mapRule = getMapRule(name); if (mapRule != null) { mapList.remove(mapRule); mapRuleTable.remove(mapRule.listen_port); if (mapRule.serverSocket != null) { try { mapRule.serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } try { saveMapRule(); } catch (Exception e) { e.printStackTrace(); } } } void updateMapRule(MapRule mapRule_origin, MapRule mapRule_new) throws Exception { if (getMapRule(mapRule_new.name) != null && !mapRule_origin.name.equals(mapRule_new.name)) { throw new Exception("映射 " + mapRule_new.name + " 已存在,请修改名称!"); } ServerSocket serverSocket; if (mapRule_origin.listen_port != mapRule_new.listen_port) { try { serverSocket = new ServerSocket(mapRule_new.getListen_port()); listen(serverSocket); mapRule_origin.using = false; if (mapRule_origin.serverSocket != null) { mapRule_origin.serverSocket.close(); } mapRule_origin.serverSocket = serverSocket; mapRuleTable.remove(mapRule_origin.listen_port); mapRuleTable.put(mapRule_new.listen_port, mapRule_new); } catch (IOException e2) { //e2.printStackTrace(); throw new Exception("端口 " + mapRule_new.getListen_port() + " 已经被占用!"); } } mapRule_origin.name = mapRule_new.name; mapRule_origin.listen_port = mapRule_new.listen_port; mapRule_origin.dst_port = mapRule_new.dst_port; saveMapRule(); } void saveMapRule() throws Exception { JSONObject json = new JSONObject(); JSONArray json_map_list = new JSONArray(); json.put("map_list", json_map_list); for (MapRule r : mapList) { JSONObject json_rule = new JSONObject(); json_rule.put("name", r.name); json_rule.put("listen_port", r.listen_port); json_rule.put("dst_port", r.dst_port); json_map_list.add(json_rule); } try { saveFile(json.toJSONString().getBytes("utf-8"), configFilePath); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); throw new Exception("保存失败!"); } } void loadMapRule() { String content; JSONObject json = null; try { content = readFileUtf8(configFilePath); json = JSONObject.parseObject(content); } catch (Exception e) { //e.printStackTrace(); } if (json != null && json.containsKey("map_list")) { JSONArray json_map_list = json.getJSONArray("map_list"); for (Object aJson_map_list : json_map_list) { JSONObject json_rule = (JSONObject) aJson_map_list; MapRule mapRule = new MapRule(); mapRule.name = json_rule.getString("name"); mapRule.listen_port = json_rule.getIntValue("listen_port"); mapRule.dst_port = json_rule.getIntValue("dst_port"); mapList.add(mapRule); ServerSocket serverSocket; try { serverSocket = new ServerSocket(mapRule.getListen_port()); listen(serverSocket); mapRule.serverSocket = serverSocket; } catch (IOException e) { mapRule.using = true; e.printStackTrace(); } mapRuleTable.put(mapRule.listen_port, mapRule); } } } MapRule getMapRule(String name) { MapRule rule = null; for (MapRule r : mapList) { if (r.getName().equals(name)) { rule = r; break; } } return rule; } public ArrayList<MapRule> getMapList() { return mapList; } public void setMapList(ArrayList<MapRule> mapList) { this.mapList = mapList; } void listen(final ServerSocket serverSocket) { Route.es.execute(new Runnable() { @Override public void run() { while (true) { try { final Socket socket = serverSocket.accept(); Route.es.execute(new Runnable() { @Override public void run() { int listenPort = serverSocket.getLocalPort(); MapRule mapRule = mapRuleTable.get(listenPort); if (mapRule != null) { Route route; if (mapClient.isUseTcp()) { route = mapClient.route_tcp; } else { route = mapClient.route_udp; } new PortMapProcess(mapClient, route, socket, mapClient.serverAddress, mapClient .serverPort, null, null, mapRule.dst_port); } } }); } catch (IOException e) { e.printStackTrace(); break; } } } }); } void saveFile(byte[] data, String path) throws Exception { FileOutputStream fos = null; try { fos = new FileOutputStream(path); fos.write(data); } finally { if (fos != null) { fos.close(); } } } }