AREA:import java.util.ArrayList;
import java.util.List;
/**
* Created by travelround on 17/5/22.
*/
public class Area {
//省市区的名字
private String name;
private List subList;
public Area(String name) {
this.name = name;
subList = new ArrayList<Area>();
}
// 将新对象添加进集合
public void addArea(Area area) {
subList.add(area);
}
// 最后一个添加的对象就是当前对象
public Area getCurrentArea() {
return subList.get(subList.size() - 1);
}
// 打印信息
public void info() {
System.out.println(name);
for (Area a : subList) {
a.info();
}
}
// 挨个层级的遍历, 返回拼接的路径
public String searchArea(String str) {
// 因为数据中存有"大连市 38"中38的字样
// 所以比较时不带38
// 以防待查询的字符串大于被比较的字符串, 而引起求子串时越界
// 所以添加长度的判断比较
String compareStr = name;
if (name.length() > str.length()) {
compareStr = name.substring(0, str.length());
}
if (compareStr.equals(str)) {
return name;
}
// 遍历子集合
for (Area a : subList) {
String ret = a.searchArea(str);
if (null != ret){
return name + "/" + ret;
}
}
return null;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
CLIENT:import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.*;
import java.net.Socket;
import java.util.List;
import java.util.Scanner;
/**
* Created by travelround on 17/5/22.
*/
public class Client {
private static final String XMLFileName = "data/code.xml";
public static void main(String[] args) throws IOException, DocumentException {
initClient();
}
public static void initClient() throws IOException, DocumentException {
// 1,创建Socket连接服务端(指定ip地址,端口),通过ip找到服务器
Socket socket = new Socket("127.0.0.1", 8888);
// 2, 获取客户端输入流
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// PrintStream有自动换行功能
PrintStream ps = new PrintStream(socket.getOutputStream());
// 读取服务器发来的数据
if ("ok".equals(br.readLine())) {
// 若服务器应答, 再进行逻辑操作
// 获取用户输入信息
Scanner scanner = new Scanner(System.in);
System.out.println("请输入待查询数据");
String content = scanner.nextLine();
System.out.println("请输入加密方式(加密方式1/加密方式2)");
String enCodeStyle = scanner.nextLine();
// 先发送加密方式
ps.println(enCodeStyle);
// 获取加密码
int code = getEncode(enCodeStyle);
// 加密数据
String enCodeContent = transcode(content, code);
// 向服务器写数据
ps.println(enCodeContent);
System.out.println("待查询数据已发送");
System.out.println(br.readLine());
}
socket.close();
}
// 转码 - 加密/解密
// 异或的特点: 与同一个数异或两次, 还原回原数值
public static String transcode(String str, int code) {
byte[] bytes = str.getBytes();
for (int i = 0; i < bytes.length; i++) {
bytes[i] ^= code;
}
return new String(bytes);
}
public static int getEncode(String str) throws DocumentException {
SAXReader sax = new SAXReader();
File file = new File(XMLFileName);
// 读取文件内容, 将内容以Document的形式呈现
Document document = sax.read(file);
// 获取根节点(students)
Element root = document.getRootElement();
return getNodes(root, str);
}
public static int getNodes(Element node, String str) {
// 获取当前节点的所有属性
List<Attribute> attr = node.attributes();
for (Attribute a : attr) {
if (str.equals(a.getValue())) {
String content = node.elementText("num");
return Integer.parseInt(content);
}
}
int code = 0;
// 获取子节点
List<Element> elements = node.elements();
// 遍历所有子节点
for (Element e : elements) {
// 递归, 调用自己
code = getNodes(e, str);
if (0 != code) {
return code;
}
}
return code;
}
}
SERVER:import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
/**
* Created by travelround on 17/5/22.
*/
public class Server {
private static final String areaFileName = "data/area.txt";
private static final String XMLFileName = "data/code.xml";
private static Area country;
public static void main(String[] args) throws IOException {
getAreaDate();
initServer();
}
// 开启线程一直等待处理客户端数据
public static void initServer() throws IOException {
ServerSocket server = new ServerSocket(8888);
while (true) {
// 内部类访问外部变量, 加final
final Socket socket = server.accept();
// 创建线程
new Thread() {
@Override
public void run() {
super.run();
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
// PrintStream有自动换行功能
PrintStream ps = new PrintStream(socket.getOutputStream());
// 向客户端应答
ps.println("ok");
// 接收解密方式
String enCodeStyle = br.readLine();
System.out.println("接收到加密方式: " + enCodeStyle);
// 获取加密码
int code = getEncode(enCodeStyle);//当加密方式为1的时候 得到的码为4,留着解码用
// 接收并解密查询数据
String str = transcode(br.readLine(), code);
System.out.println("待查询数据已接收");
// 查询信息
String retStr = country.searchArea(str);
// 将信息发送给客户端
if (null != retStr) {
ps.println(retStr);
} else {
ps.println("未找到");
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
}.start();
}
}
// 转码 - 加密/解密
// 异或的特点: 与同一个数异或两次, 还原回原数值
public static String transcode(String str, int code) {
byte[] bytes = str.getBytes();
for (int i = 0; i < bytes.length; i++) {
bytes[i] ^= code;
}
return new String(bytes);
}
// 获取省市区文档信息
public static void getAreaDate() {
// 创建国家对象
country = new Area("中国");
// 读取文件并解析
readFileByLines(areaFileName);
}
// 按行读取文档
public static void readFileByLines(String fileName) {
File file = new File(fileName);
//指针 放在外面定义 为了try和finally中能够访问
BufferedReader reader = null;
//字符流/读
try {
// 以行为单位读取文件内容,一次读一整行
reader = new BufferedReader(new FileReader(file));
String str = null;
while ((str = reader.readLine()) != null) {
// 创建数据结构
initData(str);
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
}
// 构建数据结构
//对数据进行解析处理
public static void initData(String str) {
// 区
if (str.startsWith(" ")) {
// 区
// 获取当前省
Area proA = country.getCurrentArea();
// 获取当前市
Area cityA = proA.getCurrentArea();
// 添加区到当前市
cityA.addArea(new Area(str.substring(4)));//substring截取 两种方法
} else if (!str.startsWith(" ")) {
// 省
// 构造省对象并添加到国家对象的 省集合中
Area areaP = new Area(str);
country.addArea(areaP);
} else {
// 市
// 获取当前省
Area proA = country.getCurrentArea();
// 将市添加进当前省的 市集合中
proA.addArea(new Area(str.substring(2)));
}
}
public static int getEncode(String str) throws DocumentException {
SAXReader sax = new SAXReader();
File file = new File(XMLFileName);
// 读取文件内容, 将内容以Document的形式呈现
Document document = sax.read(file);
// 获取根节点(students)
Element root = document.getRootElement();
return getNodes(root, str);
}
public static int getNodes(Element node, String str) {
// 获取当前节点的所有属性
List<Attribute> attr = node.attributes();
for (Attribute a : attr) {
if (str.equals(a.getValue())) {
String content = node.elementText("num");
return Integer.parseInt(content);
}
}
int code = 0;
// 获取子节点
List<Element> elements = node.elements();
// 遍历所有子节点
for (Element e : elements) {
// 递归, 调用自己
code = getNodes(e, str);
if (0 != code) {
return code;
}
}
return code;
}
}