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 }
版权声明:本教程版权归java123.vip所有,禁止任何形式的转载与引用。
以上是关于Java不走弯路教程(4.Client-Server模式-Server)的主要内容,如果未能解决你的问题,请参考以下文章