Java不走弯路教程(4.Client-Server模式-Server)

Posted java123vip

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java不走弯路教程(4.Client-Server模式-Server)相关的知识,希望对你有一定的参考价值。

4.Client-Server模式(1)-Server
在上一章中,我们完成了MyDataBase.java的编写,类似于一个简单的数据库功能,提供了用户验证,查询操作。
在本章中,我们将继续扩展这个程序。

数据库的数据一般存在于远程计算机(服务器)上,由多个客户进行连接,查询操作。
我们来模拟上述操作。

要访问某一台计算机上的某个程序,我们需要如下信息:
该机器的IP地址,程序所在的端口号

如下图所示:

技术分享图片

所以,服务器端程序需要在某个端口监听客户断程序的连接,连接成功后,和客户端发送消息进行通信。
在Java中提供了java.net.ServerSocket和java.net.Socket类来分别实现服务端的监听和客户端的连接操作。
如下图所示:

技术分享图片

我们写一个简单的服务器以便于理解:

技术分享图片

编译运行。

我们用telnet来尝试连接该服务器。
DOS下输入如下命令:
telnet 127.0.0.1 8000

可以看到服务器的如下输出:
listening on port 8000
get a connection.
技术分享图片

技术分享图片

技术分享图片

接下来要完成服务器和客户段的通信如下图所示:

技术分享图片

 

技术分享图片

这个通讯过程我们称为协议,即客户段和服务器段通信的规则。
因为这个规则是我们自己定义的,所以我们称他为自定义协议。

修改程序如下:
技术分享图片

在程序的开始,我们创建了一个ServerSocket对象用如下语句:
ServerSocket ss = new ServerSocket(8000);

为什么需要创建对象?
对比如下两个类:
ServerSocket
MyUtil

我们在程序中可能创建多个ServerSocket,比如一个在8000端口监听,一个在9000端口监听,这样每个ServerSocket都有不同的端口,我们称之为有不同状态的类。
针对这种情况,我们在内存中分配不同的区域来表示不同端口号(状态)的ServerSocket。
在Java中,用new关键字来分配内存中的存储区域。

MyUtil类,在整个程序执行的过程中,并不存在不同的状态,所以无需重新分配存储区域。

现在,我们可以这样理解一个class文件:
第一行声明package信息。
然后生命需要引用的package信息。
然后生命class区块,用{}括起来。

class区块内,首先声明表示状态的变量,比如表示端口号的变量port。
接下来是多个方法区块,分别用{}括起来。

方法和class信息存在于方法区内。可以理解为类信息和一条一条的指令。
一旦用new关键字分配内存后,表示状态的变量将存在于堆内存中,可以理解为数据。

也就是,经过多次new的class,
方法和class信息只有一份,存在于方法区内,
表示状态的对象有多份,存在于堆内存中。

方法调用时,CPU从方法区中读取一条一条指令分别执行,如遇到数据引用,则从堆内存中读取该对象实际数据的值。

对于静态(static)方法/变量,由于只有一份,所以可以直接使用类名称来引用,
对于非静态(static)方法/变量,因为可能存在多份,所以必须由创建的对象来引用。
注:非静态方法也是有一份,但在CPU执行的时候方法中对变量的引用会绑定到堆内存中的不同的数据。

这也是静态方法不可以访问非静态方法/变量的原因,因为是一对多的关系,无法确定需要访问哪一个,
注:非静态方法也是有一份,但在CPU执行的时候方法中对变量的引用会绑定到堆内存中的不同的数据。

暂时这么理解,随着我们学习的深入,将会有更深入的理解方式。

输入输出流的概念我们在后续章节介绍,这里暂时跳过。

line.split(" ")是把line字符创的值按照空格分隔成数组,大家可以可以扩展学习字符串操作的其他方法,比如常用的indexOf,subString等。
注:字符串是实际开发中最常用的东西,对字符串的拼接,拆分,查找,替换操作要特别熟练。

main方法后面的 throws Exception 暂时忽略,我们在后续章节讲解。

编译运行。

我们用telnet来尝试连接该服务器。
DOS下输入如下命令:
telnet 127.0.0.1 8000
Input your name password:root abc
verify ok
select * from product
文件内容
exit

可以看到服务器的如下输出:
listening on port 8000
get a connection.
技术分享图片

技术分享图片

技术分享图片

技术分享图片

MyUtil.java代码如下:

技术分享图片
  1 package util;
  2 
  3 import java.io.*;
  4 import java.util.*;
  5 
  6 
  7 public class MyUtil {
  8     
  9     public static void print(String param) {
 10         System.out.print(param);
 11     }
 12 
 13     public static void println(String param) {
 14         System.out.println(param);
 15     }
 16 
 17     public static String readln() {
 18         return readln(System.in);
 19     }
 20     
 21     public static void send(OutputStream os, String msg) {
 22         try {
 23             OutputStreamWriter osw = new OutputStreamWriter(os);
 24             PrintWriter pw = new PrintWriter(osw, true);
 25             pw.println(msg);
 26         } catch (Exception e) {
 27             e.printStackTrace();
 28         }
 29         
 30     }
 31 
 32     public static String receive(InputStream is) {
 33         return readln(is);
 34     }
 35     
 36     public static String readln(InputStream is) {
 37         try {
 38             InputStreamReader isr = new InputStreamReader(is);
 39             BufferedReader br = new BufferedReader(isr);
 40             String line = br.readLine();
 41             return line;
 42         } catch (Exception e) {
 43             e.printStackTrace();
 44             return "";
 45         }
 46     }
 47     
 48     public static String getFileContent(String fileName) {
 49         StringBuffer content = new StringBuffer();
 50         InputStream fis = null;
 51         InputStreamReader isr = null;
 52         BufferedReader br = null;
 53         try {
 54             fis = MyUtil.class.getResourceAsStream("/"+fileName);
 55             if (fis == null) {
 56                 System.out.println("File not found:[" + fileName + "]");
 57                 return content.toString();
 58             }
 59             isr = new InputStreamReader(fis, "UTF-8");
 60             br = new BufferedReader(isr);
 61             String line = null;
 62             while ((line = br.readLine()) != null) {
 63                 content.append(line);
 64                 content.append("\\r\\n");
 65             }
 66         } catch (Exception e) {
 67             e.printStackTrace();
 68             return "";
 69         } finally {
 70             try {
 71                 if (br != null) {
 72                     br.close();
 73                 }
 74                 if (isr != null) {
 75                     isr.close();
 76                 }
 77                 if (fis != null) {
 78                     fis.close();
 79                 }
 80             } catch (Exception e) {
 81                 e.printStackTrace();
 82             }
 83         }
 84         return content.toString();
 85     }
 86     
 87     public static String getFileContentBySql(String command) {
 88         try {
 89             command = command.replaceAll(";", "");
 90             StringBuffer result = new StringBuffer(); // select username, password from person where username = ‘aaa‘
 91             int selectPos = command.indexOf("select");
 92             int fromPos = command.indexOf("from");
 93             int wherePos = command.indexOf("where");
 94             if (selectPos == -1 || fromPos == -1) {
 95                 return "incorrect SQL.";
 96             }
 97             String columnStr = command.substring(selectPos + "select".length(), fromPos).trim();
 98             String tableStr;
 99             String whereStr;
100             if (wherePos == -1) {
101                 tableStr = command.substring(fromPos + "from".length()).trim();
102                 whereStr = "";
103             } else {
104                 tableStr = command.substring(fromPos + "from".length(), wherePos).trim();
105                 whereStr = command.substring(wherePos + "where".length()).trim();
106             }
107             List<String> fileHeader = getFileHeaderList(tableStr + ".db");
108             if (fileHeader.size() == 0) {
109                 return result.toString();
110             }
111             List<Map<String, String>> fileContent = getFileContentList(tableStr + ".db");
112             String[] columnArray = null; // print header
113             if (columnStr.equals("*")) {
114                 columnArray = new String[fileHeader.size()];
115                 int i = 0;
116                 for (String column : fileHeader) {
117                     result.append(column);
118                     if (i != fileHeader.size() - 1) {
119                         result.append(",");
120                     }
121                     columnArray[i++] = column;
122                 }
123                 result.append("\\r\\n");
124             } else { // check
125                 boolean checkSelect = true;
126                 columnArray = columnStr.split(",");
127                 for (int i = 0; i < columnArray.length; i++) {
128                     checkSelect = false;
129                     for (int j = 0; j < fileHeader.size(); j++) {
130                         if (columnArray[i].trim().equals(fileHeader.get(j))) {
131                             checkSelect = true;
132                             break;
133                         }
134                     }
135                     if (!checkSelect) {
136                         String falseColumn = columnArray[i].trim();
137                         result.append("Unknow column:" + falseColumn + "\\r\\n");
138                         break;
139                     }
140                 }
141                 if (!checkSelect) {
142                     return result.toString();
143                 } // print header
144                 for (int i = 0; i < columnArray.length; i++) {
145                     result.append(columnArray[i]);
146                     if (i != columnArray.length - 1) {
147                         result.append(",");
148                     } else {
149                         result.append("\\r\\n");
150                     }
151                 }
152             } // print content
153             if (!whereStr.equals("")) {
154                 String[] whereExp = whereStr.split("and"); // for each row check where condition
155                 for (Map<String, String> rowMap : fileContent) {
156                     boolean checkRow = true;
157                     for (int i = 0; i < whereExp.length; i++) {
158                         String key = whereExp[i].split("=")[0].trim();
159                         String value = whereExp[i].split("=")[1].trim();
160                         String fileContentValue = rowMap.get(key);
161                         if (!value.equals(fileContentValue)) {
162                             checkRow = false;
163                         }
164                     }
165                     if (checkRow) {
166                         for (int i = 0; i < columnArray.length; i++) {
167                             result.append(rowMap.get(columnArray[i]));
168                             if (i != columnArray.length - 1) {
169                                 result.append(",");
170                             } else {
171                                 result.append("\\r\\n");
172                             }
173                         }
174                     }
175                 }
176             } else {
177                 for (Map<String, String> rowMap : fileContent) {
178                     for (int i = 0; i < columnArray.length; i++) {
179                         result.append(rowMap.get(columnArray[i]));
180                         if (i != columnArray.length - 1) {
181                             result.append(",");
182                         } else {
183                             result.append("\\r\\n");
184                         }
185                     }
186                 }
187             }
188             return result.toString();
189         } catch (Exception e) {
190             return "Incorrect SQL.";
191         }
192     }
193 
194 
195     private static List<String> getFileHeaderList(String fileName) {
196         List<String> result = new ArrayList<String>();
197         InputStream fis = null;
198         InputStreamReader isr = null;
199         BufferedReader br = null;
200         try {
201             fis = MyUtil.class.getResourceAsStream("/"+fileName);
202             if (fis == null) {
203                 System.out.println("File not found:[" + fileName + "]");
204                 return result;
205             }
206             isr = new InputStreamReader(fis, "UTF-8");
207             br = new BufferedReader(isr);
208             String line = null;
209             if ((line = br.readLine()) != null) {
210                 String[] rowInfo = line.split(",");
211                 for (int i = 0; i < rowInfo.length; i++) {
212                     result.add(rowInfo[i]);
213                 }
214             }
215         } catch (Exception e) {
216             e.printStackTrace();
217             return result;
218         } finally {
219             try {
220                 if (br != null) {
221                     br.close();
222                 }
223                 if (isr != null) {
224                     isr.close();
225                 }
226                 if (fis != null) {
227                     fis.close();
228                 }
229             } catch (Exception e) {
230                 e.printStackTrace();
231             }
232         }
233         return result;
234     }
235 
236     private static List<Map<String, String>> getFileContentList(String fileName) {
237         List<Map<String, String>> result = new ArrayList<Map<String, String>>();
238         InputStream fis = null;
239         InputStreamReader isr = null;
240         BufferedReader br = null;
241         try {
242             fis = MyUtil.class.getResourceAsStream("/"+fileName);
243             if (fis == null) {
244                 System.out.println("File not found:[" + fileName + "]");
245                 return result;
246             }
247             isr = new InputStreamReader(fis, "UTF-8");
248             br = new BufferedReader(isr);
249             String[] headerInfo = null;
250             String line = null;
251             while ((line = br.readLine()) != null) {
252                 if (headerInfo == null) {
253                     headerInfo = line.split(",");
254                 } else {
255                     String[] rowInfo = line.split(",");
256                     if (rowInfo.length != headerInfo.length) {
257                         System.out.println("Parse file error:[" + fileName + "]" + line);
258                         return result;
259                     }
260                     Map<String, String> rowInfoMap = new HashMap<String, String>();
261                     for (int i = 0; i < rowInfo.length; i++) {
262                         rowInfoMap.put(headerInfo[i], rowInfo[i]);
263                     }
264                     result.add(rowInfoMap);
265                 }
266             }
267         } catch (Exception e) {
268             e.printStackTrace();
269             return result;
270         } finally {
271             try {
272                 if (br != null) {
273                     br.close();
274                 }
275                 if (isr != null) {
276                     isr.close();
277                 }
278                 if (fis != null) {
279                     fis.close();
280                 }
281             } catch (Exception e) {
282                 e.printStackTrace();
283             }
284         }
285         return result;
286     }
287 
288 }
MyUtil.java

 

版权声明:本教程版权归java123.vip所有,禁止任何形式的转载与引用。

 























































































以上是关于Java不走弯路教程(4.Client-Server模式-Server)的主要内容,如果未能解决你的问题,请参考以下文章

Java学习不走弯路教程(12 Container容器)

Java学习不走弯路教程(14 代码结构整理)

Java学习不走弯路教程(3.从文件内容查询开始)

Java学习不走弯路教程(7.Eclipse环境搭建)

Java学习不走弯路教程(3.从文件内容查询开始)

Java学习不走弯路教程(2.Eclipse环境搭建)