Java学习不走弯路教程(4.用SQL查询远程服务器的文件)
一. 前言
在前教程中,介绍了用sql查询本地文件。
程序代码请从下载。
本章将在的基础上,进一步扩展程序。
实际的生产环境中,一般查询的文件都放在远程的文件或数据服务器上,
下面我将带大家一步一步实现远程查询的程序。
注:
1.本文针对初学java的同学训练学习思路,请不要太纠结于细节问题。
2.本文旨在达到抛砖引玉的效果,希望大家扩展本例子,以学到更多知识的精髓。
二. 写给初学java的同学
在介绍本章内容之前,首先介绍一下java的学习方法。
相信大家在看本文的时候已经已经拿到了各种java学习路径,大体都是一样。
我想说的是,不要让知识的学习成为负担,java技术种类繁多,是无论如何也学不完的。
正确的学习方法是兴趣驱动,实例驱动。
即通过一个简单的实例,不断加入所学知识进行扩展,最终扩展为一个大项目,达到系统学习,学以致用的效果。
三. 步入正题
话不多说,大家自己理解,下面步入正题:
本章系统的流程如下:
【客户端】
1.连接远程服务器。
2.向远程服务器发送查询sql。
3.将远程服务器反馈的查询结果输出。
【服务器】
1.在指定端口监听,等待客户端连接。
2.有客户端连接后,读取客户端传来的sql。
3.调用文件查询模块,查询数据。
4.将查询的数据反馈给客户端。
5.转到步骤1。
工程的结构如下:
其中文件查询模块复用上一章的代码,在此不做讲解。
我们着重介绍客户端与服务器通讯的过程。
要想与网络中的一台机器的某个程序进行通讯,首先我们需要定位这台机器的某个程序。
ip地址标识了网络中唯一的机器,这台机器的不同的端口则标示了不同的程序。
所以,客户端要知道连接服务器的ip地址和端口号,来完成于服务器的连接。
而服务器程序之需要在特定的端口监听,等待客户端的连接。
服务器连接成功后,即可通过输入输出流进行通讯。
通讯协议分为两种tcp/ip协议和udp协议:
前者能维持稳定的通讯,确保每一个发送的信息对方都收到。
后者只负责发送信息而不管对方有没有收到。
比如文字通讯的软件一般采用tcp/ip协议,因为要确保发送的每条消息对方都能收到。
音频视频通讯软件一般采用udp协议,因为缺了一点信息也不影响对声音图像的识别。
本项目我们采用tcp/ip协议,在java中用serversocket和socket封装了tcp/ip协议,所以我们直接拿来用即可,感兴趣的同学可以研究一下底层的实现。
四. 服务端程序
我们首先看单个客户端与服务器的通讯流程,如下图所示:
多个客户端连接后,如下图所示:
所以,我们首先做一个类clientthread,用来负责服务器与客户端通讯的线程,代码如下:
1 /** 2 * 3 * @author http://www.java123.vip 4 * 5 */ 6 public class clientthread implements runnable{ 7 8 private socket socket; 9 private bufferedreader br; 10 private printwriter pw; 11 12 public clientthread(socket socket) { 13 try { 14 15 // 创建输入输出流 16 inputstream is = socket.getinputstream(); 17 inputstreamreader isr = new inputstreamreader(is); 18 br = new bufferedreader(isr); 19 20 outputstream os = socket.getoutputstream(); 21 outputstreamwriter osw = new outputstreamwriter(os); 22 pw = new printwriter(osw,true); 23 24 } catch (ioexception e) { 25 e.printstacktrace(); 26 } 27 } 28 29 public void run() { 30 31 getfile gf = new getfile("c:/temp/"); 32 33 while(true) { 34 try { 35 36 // 读取客户端的一行信息 37 string message = br.readline(); 38 system.out.println("get message:"+message); 39 40 // 用冒号(:)来分隔信息的头与内容 41 string header = message.split(":")[0]; 42 string body = message.substring(message.indexof(":")+1); 43 44 // 查询请求 45 if(header.equals("query")) { 46 string result = gf.queryfile(body); 47 pw.println(result); 48 49 // 断开连接请求 50 }else if(header.equals("bye")) { 51 if(socket != null) { 52 socket.close(); 53 } 54 break; 55 } 56 57 } catch(ioexception e) { 58 e.printstacktrace(); 59 } catch (exception e) { 60 e.printstacktrace(); 61 } 62 } 63 } 64 65 }
服务器实现代码如下:
1 /** 2 * 3 * @author http://www.java123.vip 4 * 5 */ 6 public class fileviewserver { 7 8 private int port; 9 10 public fileviewserver(int port) { 11 this.port = port; 12 } 13 14 /** 15 * 启动服务器 16 */ 17 public void startserver() { 18 try { 19 20 serversocket ss = new serversocket(port); 21 system.out.println("listening at port:"+port); 22 23 while(true) { 24 socket s = ss.accept(); 25 system.out.println("get connection:"+s.getinetaddress().tostring()); 26 27 // 得到连接后,启动新线程负责通讯 28 clientthread clientthread = new clientthread(s); 29 new thread(clientthread).start(); 30 } 31 32 } catch (ioexception e) { 33 e.printstacktrace(); 34 } 35 } 36 37 public static void main(string[] args) { 38 fileviewserver fvs = new fileviewserver(8000); 39 fvs.startserver(); 40 } 41 }
五. 客户端程序
我们需要做三个方法:
・连接服务器方法
・断开服务器方法
・查询远程文件方法
代码如下:
连接服务器方法
1 private socket socket; 2 private bufferedreader br; 3 private printwriter pw; 4 5 /** 6 * 连接远程服务器 7 * 8 * @param ip 9 * @param port 10 */ 11 public void connect(string ip, int port) { 12 try { 13 14 // 连接服务器 15 socket = new socket(ip, port); 16 17 // 创建输入输出流 18 inputstream is = socket.getinputstream(); 19 inputstreamreader isr = new inputstreamreader(is); 20 br = new bufferedreader(isr); 21 22 outputstream os = socket.getoutputstream(); 23 outputstreamwriter osw = new outputstreamwriter(os); 24 pw = new printwriter(osw,true); 25 26 } catch (ioexception e) { 27 e.printstacktrace(); 28 } 29 } 30
断开服务器方法
1 2 /** 3 * 断开连接 4 */ 5 public void disconnect() { 6 try { 7 8 // 发送断开连接请求 9 pw.println("bye:bye"); 10 socket.close(); 11 } catch (ioexception e) { 12 e.printstacktrace(); 13 } 14 } 15
查询远程文件方法
1 /** 2 * 查询 3 * 4 * @param sql 5 * @return 6 */ 7 public string query(string sql) { 8 9 stringbuffer result = new stringbuffer(""); 10 11 try { 12 13 // 发送查询请求 14 pw.println("query:"+sql); 15 16 while(true) { 17 18 // 读取查询结果的每一行 19 string queryresultline = br.readline(); 20 21 // 读到空字符串表示结果读取完毕 22 if("".equals(queryresultline)) { 23 break; 24 25 // 否则,把读到的内容存起来 26 }else { 27 result.append(queryresultline); 28 result.append("\n"); 29 } 30 } 31 } catch (ioexception e) { 32 e.printstacktrace(); 33 } 34 35 // 返回查询结果 36 return result.tostring(); 37 } 38
六. 测试
最后我们来测试这个程序,测试代码如下:
1 2 /** 3 * 测试 4 * @param args 5 */ 6 public static void main(string[] args) { 7 fileviewclient fvc = new fileviewclient(); 8 fvc.connect("127.0.0.1",8000); 9 10 string sql1 = "select * from abc.csv "; 11 string sql2 = "select id from abc.csv "; 12 string sql3 = "select id,username from abc.csv where id=2 "; 13 string sql4 = "select id,username from abc.csv where username=abc and password=aaa "; 14 string sql5 = "select id,username from abc.csv where username=abc and password=bbb "; 15 16 system.out.println("execute:"+sql1); 17 system.out.println(fvc.query(sql1)); 18 19 system.out.println("execute:"+sql2); 20 system.out.println(fvc.query(sql2)); 21 22 system.out.println("execute:"+sql3); 23 system.out.println(fvc.query(sql3)); 24 25 system.out.println("execute:"+sql4); 26 system.out.println(fvc.query(sql4)); 27 28 system.out.println("execute:"+sql5); 29 system.out.println(fvc.query(sql5)); 30 31 fvc.disconnect(); 32 }
首先启动服务器,输出如下:
listening at port:8000
启动客户端测试程序:
客户端输出如下:
execute:select * from abc.csv 1,abc,aaa 2,def,bbb 3,xyz,ccc execute:select id from abc.csv 1 2 3 execute:select id,username from abc.csv where id=2 2,def execute:select id,username from abc.csv where username=abc and password=aaa 1,abc execute:select id,username from abc.csv where username=abc and password=bbb
服务器输出如下:
listening at port:8000 get connection:/127.0.0.1 get message:query:select * from abc.csv get message:query:select id from abc.csv get message:query:select id,username from abc.csv where id=2 get message:query:select id,username from abc.csv where username=abc and password=aaa get message:query:select id,username from abc.csv where username=abc and password=bbb get message:bye:bye
完整代码请在下载
如有问题,大家来我的网站进行提问。
七. 后续
本例为通过简单的sql语句查询远程存在的文件,大家可以扩展此程序,比如用线程池来管理线程,对于异常信息的处理等。
后续章节我将在此程序的基础上,其支持jdbc接口,然后换成数据库,并且一步一步实现orm,service,http查询等功能。
版权声明:本教程版权归java123.vip所有,禁止任何形式的转载与引用。
原帖发表于:https://www.cnblogs.com/java123vip/p/9732445.html