a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 310|回复: 5

[专业语言] JAVA认证:质数判别示例分析

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
该示例实现的功能是质数判断,程序实现的功能为客户端程序接收用户输入的数字,然后将用户输入的内容发送给服务器端,服务器端判断客户端发送的数字是否是质数,并将判断的结果反馈给客户端,客户端根据服务器端的反馈显示判断结果。
( D6 G; W9 w: v. q    质数的规则是:最小的质数是2,只能被1和自身整除的自然数。当用户输入小于2的数字,以及输入的内容不是自然数时,都属于非法输入。
3 n9 G8 [) F% Q* n7 V$ v) w    网络程序的功能都分为客户端程序和服务器端程序实现,下面先描述一下每个程序分别实现的功能:
! x2 h0 f+ j7 X7 }$ }    1、  客户端程序功能:( T) F7 X6 r% K, L3 t; r( S
    a)         接收用户控制台输入  J: z# Y# H7 a; n7 j& ]
    b)         判断输入内容是否合法; r# h4 I! Z2 ~& C) e+ Q, e
    c)         按照协议格式生成发送数据% d8 ]2 a1 i. ^; v! u
    d)         发送数据/ M' p2 G  z1 P2 i% Z4 d% R( N" P
    e)         接收服务器端反馈3 k- q* E  G( u. a! n
    f)          解析服务器端反馈信息,并输出
2 ?( J! ^- j7 W# t6 B+ x. Z    2、  服务器端程序功能:
! w4 \' ]: I: g6 t+ P    a)         接收客户端发送数据8 M, x( \0 k$ _/ M% ?
    b)         按照协议格式解析数据6 a: |- f2 ]0 m" ~5 W' `
    c)         判断数字是否是质数1 X( I( ]5 o, z
    d)         根据判断结果,生成协议数据
! c/ m3 \2 O0 C/ d! `    e)         将数据反馈给客户端
1 |! x0 {3 a( f. U    分解好了网络程序的功能以后,就可以设计网络协议格式了,如果该程序的功能比较简单,所以设计出的协议格式也不复杂。
  A- L/ S& \. l: |( R6 L2 @    客户端发送协议格式:
* g; F) E2 D( v5 C- R3 C- Q- f    将用户输入的数字转换为字符串,再将字符串转换为byte数组即可。
9 N* W, Y& \7 c5 S: ?' \! ~    例如用户输入16,则转换为字符串“16”,使用getBytes转换为byte数组。* J. }' Q* w1 |
    客户端发送“quit”字符串代表结束连接
2 z/ L7 |. N% D, k/ h0 X    服务器端发送协议格式:- _/ D9 W, ~' _( u" q) u
    反馈数据长度为1个字节。数字0代表是质数,1代表不是质数,2代表协议格式错误。: k, e) h! R2 v; ?# a; Z7 j
    例如客户端发送数字12,则反馈1,发送13则反馈0,发送0则反馈2。
" u3 h+ R. @$ J8 I8 o& K    功能设计完成以后,就可以分别进行客户端和服务器端程序的编写了,在编写完成以后联合起来进行调试即可。
- W# o) ?+ \$ G% `" z* f    下面分别以TCP方式和UDP方式实现该程序,注意其实现上的差异。不管使用哪种方式实现,客户端都可以多次输入数据进行判断。对于UDP方式来说,不需要向服务器端发送quit字符串。
回复

使用道具 举报

 楼主| 发表于 2012-8-4 12:44:45 | 显示全部楼层

JAVA认证:质数判别示例分析

以TCP方式实现的客户端程序代码如下:: L' t5 [; V$ q/ r2 H0 M
    package example1;+ Y0 F4 o* J1 T* ]& m+ U0 `
    import java.io.*;6 K! \+ [) @. q
    import java.net.*;- P* B4 D6 T/ V- ]: g  L
    /**
  i/ h: k7 }3 a  _$ P) [9 B    * 以TCP方式实现的质数判断客户端程序
1 K" F5 a6 _! ~, B    */
% @3 v' s" g. N* n5 {7 G9 M    public class TCPPrimeClient {" ~5 d+ W3 K  s6 \$ a5 J
    static BufferedReader br;2 u' L- e% g( K* Z2 E0 V
    static Socket socket;% Y; {1 U4 J# F9 [, ?
    static InputStream is;$ D0 E: J8 f/ w* r2 S0 x7 D
    static OutputStream os;
  i1 i2 c+ a6 H4 {. m8 B6 e& W; E    /**服务器IP*/4 t5 G$ n& m" Y6 }6 z& D% ]' @
    final static String HOST = "127.0.0.1";# u1 [. k7 o& ]) X3 {
    /**服务器端端口*/
$ E. ^) k2 N8 B7 Y- n7 b. L+ E1 M    final static int PORT = 10005;) A% A# `4 I) Q4 k+ h# |
    public static void main(String[] args) {
$ w. n' d7 R# f! I; ^; f( i1 s" t    init(); //初始化
( r6 X% f1 W7 `) T    while(true){" b8 ~5 Q2 O+ D8 y5 m
    System.out.println("请输入数字:");" Z! g/ p( r4 x$ }
    String input = readInput(); //读取输入
* G0 O: c' Q/ V0 `3 r    if(isQuit(input)){ //判读是否结束
$ C1 G6 x& o7 Y" G5 W; w4 A: G" M    byte[] b = "quit".getBytes();
1 i1 D! e' |7 w    send(b);' Z3 W- w5 l: L; p
    break; //结束程序
* U9 G5 s5 a+ b% ^$ K    }
  b+ y2 k2 B4 A    if(checkInput(input)){ //校验合法
8 W! e9 b% Y! S0 o8 ^9 o! J    //发送数据
% y. b5 O% q6 f5 D3 V    send(input.getBytes());) Y0 ]6 Y; k3 T# J, W3 k% x
    //接收数据) q% w7 U0 M6 G, c
    byte[] data = receive();
* }/ [8 \& h0 B4 Y3 m( b; l    //解析反馈数据& U7 ?/ A# G& w  i
    parse(data);# X. X# {# B; [6 k" y
    }else{
8 q+ a* v& s( ~* F; @    System.out.println("输入不合法,请重新输入!");
+ }8 x! @* v8 x    }) q% r6 j8 z" B9 ^' i  U2 S: f
    }0 _4 ~5 d" C& b! J6 ~1 S/ Z2 c0 p
    close();  //关闭流和连接
) ~/ h- G/ c0 E    }7 c- o1 [! |  L8 V/ h8 j
    /**2 o- [2 y' G, V- t9 r0 z. Q
    * 初始化  D! z5 P3 l( H7 E; t" G" I; z
    */1 w' p* t  g! @5 w* g
    private static void init(){
5 e7 x, z! A& B5 O  C; ]: s    try {
3 P) ?: Q, ?/ Z& M    br = new BufferedReader(
: E, x" K& W- z& V9 ~4 t    new InputStreamReader(System.in));
+ b; y$ j6 h6 k% T    socket = new Socket(HOST,PORT);' [% ^8 Q  e% c' \; r9 Q. h% Q
    is = socket.getInputStream();
' E+ U2 o0 b& F$ C, O& d& h    os = socket.getOutputStream();' K( L/ X: b2 A( i1 z' r
    } catch (Exception e) {}
) {4 @% ]. S& j. U5 G3 E) W9 R* d  F    }7 K. n4 ~9 J& k. f2 v6 W% D
    /**7 r6 m; x3 J+ f, @5 W) Z
    * 读取客户端输入
$ o. y/ M3 U- D; I' @( m    */
4 C; D. \/ Z7 n( i    private static String readInput(){
5 h. J* _7 p9 P    try {
( y* J# b5 s" v1 i    return br.readLine();
7 N& V( y4 N6 Q) J$ q5 _* P! R; d$ M    } catch (Exception e) {! [0 T4 V6 C7 E' h1 h
    return null;
" ]" b1 {9 I- @9 j. p, Q, C6 x; X, u    }7 b+ v$ H5 r) c
    }- _2 k; `  o$ g+ x
    /**
4 d, G2 W4 B$ |5 w! L2 _3 {    * 判断是否输入quit9 [2 m. E/ `# s9 Y
    * @param input 输入内容  C1 e1 ~. r( }1 K6 X
    * @return true代表结束,false代表不结束
4 D. p; e) E/ t* K* Q5 L1 L$ M    */
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-4 12:44:46 | 显示全部楼层

JAVA认证:质数判别示例分析

private static boolean isQuit(String input){
# H  H1 B- j! u* E    if(input == null){
3 T# D, Y1 n/ N, u5 u" z5 d    return false;+ W& Z, N6 Z6 G' P! j/ X
    }else{) H0 A0 H* {5 L3 w
    if("quit".equalsIgnoreCase(input)){, K. s1 t7 m2 d8 \4 N; N  \- s7 n+ B
    return true;
9 K; q* m2 R% Y4 }9 \    }else{5 P; A% j+ E1 S5 X, a3 N# F
    return false;
8 ], X: ~& n  O# G- |8 V    }
6 Q7 |0 i: ?0 u4 `% L0 z    }
# I6 _+ Z& T' W0 h0 k# O3 e    }
5 L0 \( x3 J! J4 D1 I/ O" v# o    /**+ i1 P% W% h  U: i4 x/ S: P/ M& o0 S
    * 校验输入
) _- [7 N  P5 t    * @param input 用户输入内容
5 M; u$ V" {0 p( z. S$ q$ S1 E1 w    * @return true代表输入符合要求,false代表不符合1 Q) Q, m1 f( o, W) j
    */' T: h+ i2 R" u' x! Y9 K5 K0 ^
    private static boolean checkInput(String input){* S  e8 ^: X: E# c
    if(input == null){3 I9 z( A  D# t( x
    return false;
& Y; m& X6 @6 E3 ~, l6 O3 @    }
+ g3 o7 d2 `4 M    try{2 R6 m7 U$ G5 t( `" [) L% {
    int n = Integer.parseInt(input);
# W1 T% ~( L, R, E+ x    if(n >= 2){6 ^4 T7 ?/ {+ q
    return true;4 [! p+ @+ Q7 V4 p
    }else{
8 x. Q; O7 X+ s6 c4 M    return false;
& a# J7 A$ S  ], V    }
" Q& y. V. h9 q$ L    }catch(Exception e){# [/ J: l- L9 b+ a8 E; X
    return false;  //输入不是整数0 M2 e# [3 s4 J5 c, r
    }
4 S! _) x+ L. F8 e    }
. ^& G" {% _6 q4 m    /**
9 J1 D& z5 z' I, \    * 向服务器端发送数据" L) Y( e" U9 w& E
    * @param data 数据内容
" S8 m% C+ \" U4 e    */0 K% ?" }% Z0 R2 e$ k) @
    private static void send(byte[] data){, A7 N2 K8 P3 I1 V9 o6 U1 M
    try{3 c7 k" D5 R: R
    os.write(data);
% A2 }! |9 Q' o- I. [; s( |    }catch(Exception e){}
* B! k4 |& R, H" ~, Z% P    }' `$ o5 C2 D$ {( m: W: W
    /**/ k' k4 V* H, g: \6 i) _
    * 接收服务器端反馈& P5 L* E' G% e+ U
    * @return 反馈数据, G- r9 |- D, ]( g. k3 y
    */
9 _2 b- z6 a  C+ F) S3 {! F, H: t    private static byte[] receive(){, I& K( S8 ^" |/ D% u  H
    byte[] b = new byte[1024];4 I$ ^4 \+ c4 w4 f" h/ V
    try {( D  H* }/ j6 n7 V# k
    int n = is.read(b);) L& x: z$ U& [! v6 v
    byte[] data = new byte[n];
* U0 Q" k, }6 f" n2 `    //复制有效数据
2 w0 a: @8 o# ~) ?    System.arraycopy(b, 0, data, 0, n);& X* n) B/ G) _; c' R
    return data;  |  \9 X5 v# r% H* M2 d7 Y
    } catch (Exception e){}
, r, p- \$ L, n1 Q4 ?6 d    return null;$ x" e4 [7 n/ a' _  ?
    }' M, w6 L% y% B/ S, M! N% D+ X: ~2 `
    /**
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-4 12:44:47 | 显示全部楼层

JAVA认证:质数判别示例分析

* 解析协议数据
' x4 g/ W1 `- |9 s) \3 `    * @param data 协议数据
: W4 x. L# o7 o; l% e8 Q6 Y! }( j    */* L0 H$ y$ i  C9 h  a  N0 }: b- [
    private static void parse(byte[] data){* Y% c9 q- a4 i: P; ^1 K$ X1 u
    if(data == null){
0 M6 Q* p0 b( Z: e0 m    System.out.println("服务器端反馈数据不正确!");
  T, j3 a4 X2 i8 g2 ~9 q    return;
+ {! p* `+ W$ d& b+ U$ x    }7 \9 H: o: S6 R7 p
    byte value = data[0]; //取第一个byte
, |/ |! Y7 U3 R0 w( T7 a    //按照协议格式解析
* l, @+ H8 X. h6 f6 ~( n    switch(value){1 U* F4 j0 V* ]: j4 m& z: b9 a
    case 0:* d6 z0 Y1 C, |# C% U' e
    System.out.println("质数");* }' v" p& d' C* k* Z" }1 M* e4 `
    break;/ T8 x  @& s2 p1 d$ ~3 B
    case 1:( |% o$ `( [2 b5 l6 W! V
    System.out.println("不是质数");
; g/ r1 V- c% o$ F9 ]* \    break;1 k: J' u8 V, z3 }8 b
    case 2:
0 _$ k0 X8 j' s$ T+ z% R3 {6 n! o: L    System.out.println("协议格式错误");. |7 |& H1 g5 I) a6 `
    break;  k/ X$ K. [- F8 Y8 |- t
    }
, ~& Z# h, C+ d# P$ r8 d4 G' i% r    }
2 D/ u$ ]/ M. H+ f( u    /**) Y% I; h+ L- h- A. a
    * 关闭流和连接
6 [: V0 U$ z) C+ Z2 s; \- ^    */- J7 S; s" k, [3 ]  P
    private static void close(){8 R- O9 V% j* R9 x4 C6 @  D
    try{1 ^2 x2 D& M5 @2 E; ?3 d
    br.close();) U$ r0 ]5 f4 g: J' N
    is.close();& j( Y1 H& g/ o) q5 G' O
    os.close();
1 `, [8 O0 J4 h6 f" F- Z) L+ ]    socket.close();
9 a/ ?9 g% {) e) b# C# f0 S2 ]% D    }catch(Exception e){
4 A7 G+ I4 z8 }: @2 t/ s. l  I    e.printStackTrace();1 A  n* {: m9 h1 m; `  H
    }
, C- W* }! X1 w" U3 ~    }9 Y; @; K0 z8 M3 C/ m  g
    }
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-4 12:44:48 | 显示全部楼层

JAVA认证:质数判别示例分析

  清单 1 中的第一条语句建树了一个新的 groovy.sql.Sql 对象。这是一个尺度 JDBC 类集的瘦 Groovy facade,搜罗 Connection、Statement 和 ResultSet。您可能已经认出了 newInstance 工场体例的四个参数了:JDBC 毗连字符串、用户名、密码以及 JDBC 驱动轨范(在 grails-app/conf/DataSource.groovy 中也可以找到不异值)。</p>  下一条语句建树了 groovy.xml.MarkupBuilder。该类许可您动态建树 XML 文档。
2 @, n# D) R( A: J/ }& y2 j! x  最后一条语句(以 x.airports 开首)建树了 XML 树。XML 文档的根元素为 airports。它还为数据库的每一行建树了一个 airport 元素,该元素带有 id 属性。嵌套于 airport 元素的元素有 version、name 和 city 元素(想体味更多关于 Groovy Sql 和 MarkupBuilder 用途的信息,参见 参考资料)。% f$ e( _! Z) t' F0 m1 O& e* H
  清单 2 展示了由此获得的 XML:0 s9 G& y- P0 y- K
  清单 2. 来自备份剧本的 XML 输出
2 L8 Y1 S: V' j& p  |/ C; h! G: a* @) {
  
0 i0 \& R: j- \/ W    2. I# I0 ?/ I, Q( [; }5 |; X& g
    Denver International Airport% U8 c1 `' g0 U4 `
    Denver
6 Q/ {6 U3 @/ j* |+ w; ]9 M    CO
1 c& c% ~# F+ D5 O    US$ N$ d3 [& q( P6 C* _
    den) \7 J3 F; p+ X8 Q! V$ v4 ~% ~
    39.8583188+ r) ]- W5 Q4 F' A) L
    -104.66746745 v* E% p: Z+ U: y1 t
  2 `' o  y2 v  C* m! }
  ...
+ H( g: ?' R3 h8 p7 K  ...
* X% a- |5 Z# t7 e9 J   在备份剧本中,必然要按照主键挨次拖出记实。当恢复这个数据时,必然要按不异的挨次插入值,以确奔窃攸值同样匹配(关于这一点我将不才一小节进一步胪陈)。  注重,该剧本是完全自力于 Grails 框架的。要使用它,就必然要在您的系统上安装 Groovy(参见 参考资料,查找下载与安装声名)。此外,类路径中必然要有 JDBC 驱动轨范 JAR。可以在运行剧本时进行指定。在 UNIX&reg; 中,要输入:# a1 f8 {, x% x  P  r5 D
  groovy -classpath /path/to/mysql.jar:. backupAirports.groovy   当然了,在 Windows&reg; 上,响应的文件路径和 JAR 分隔符是分歧的。在 Windows 中,则需要输入:  e3 k- H& J' d% y! d+ \  w
  groovy -classpath c:pathtomysql.jar;. backupAirports.groovy   因为我经常使用 MySQL,所以我将一份该 JAR 的副本保留在了我的主目录(在 UNIX 上为 /Users/sdavis,在 Windows 上为 c:Documents and Settingssdavis)中的 .groovy/lib 目录中。昔时夜呼吁走运行 Groovy 剧本时,该目录中的 JAR 会自动包含在类路径中。
$ L/ P) ^5 C+ D0 N8 Z4 s6 E  清单 1 中的剧本将输出写到了屏幕。要将数据保留在一个文件中,可以在运行剧本时重定向输出:4 ?; J3 z6 r* i/ \7 [3 G
  groovy backupAirports.groovy > airports.xml   恢复数据
/ i8 ^2 n1 o; L2 w: Y0 L' `. E. }( U+ v; Q* \+ O5 b8 Q8 @
  年夜数据库中获掏出数据仅仅是成功了一半。还要再将数据恢复到数据库中。清单 3 中展示的 restoreAirports.groovy 剧本用 Groovy XmlParser 读入了 XML,机关了一个 SQL insert 语句,并用了一个 Groovy SQL 对象来执行该语句(要体味更多关于 XmlParser的信息,参见 参考资料)。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-4 12:44:49 | 显示全部楼层

JAVA认证:质数判别示例分析

</p>  清单 3. 年夜 XML 中恢复数据库记实的 Groovy 剧本8 q1 Y" ~" K; k; @: C( H, V5 [
if(args.size()){
* }& T( B/ V, v0 {   f = new File(args[0])
/ f% @2 W# j) _   println f% G! e! `% y0 L, E+ Y4 @7 @: f
0 R5 k% E8 ~/ z( h! B
   sql = groovy.sql.Sql.newInstance(
/ ]6 R2 [/ b0 J( z/ I( z( e1 P3 u* A9 b      "jdbc:mysql://localhost/aboutgroovy?autoReconnect=true",9 ~/ a1 _; n% E
      "grails",
5 e. T1 h- E3 d/ `: a) M' n      "server",- q6 k( @. `- j! C8 Y
      "com.mysql.jdbc.Driver")
- ]" |- R! o# f4 u5 Z3 g0 q
9 a! v2 o& g1 g7 c; R: ^   items = new groovy.util.XmlParser().parse(f)( v' k2 c. s  G& |
   items.item.each{item ->* }  `  L$ W& M/ U
     println "${item.@id} -- ${item.title.text()}"* J$ N2 Y9 ]) v4 I5 g4 \' S4 v
      sql.execute(7 P& Q! e$ e2 A& l6 p# H+ ]1 y* P  a; n
         "insert into item (version, title, short_description, description, ; }# z. K8 w9 E1 ]7 D+ V9 F
                 url, type, date_posted, posted_by) values(?,?,?,?,?,?,?,?)"," j9 i( {: ]3 D3 J
         [0, item.title.text(), item.shortDescription.text(), item.description.text(),
' K) b( ?+ [* `* {0 I             item.url.text(), item.type.text(), item.datePosted.text(),
8 j% p' i5 A- c! p) G             item.postedBy.text()]9 K- W  G- R, \+ m1 _
         )" {2 g( c* |" ~! [# Z+ l9 h3 _& L$ V
   }
3 Z, E; k  E6 y" E}
6 c9 ?" B+ O! Y) T6 t% uelse{
5 f4 r+ r. O4 ]$ v1 T# t0 K; M. \: T   println "USAGE: itemsRestore [filename]". k' r3 Z4 c; K& n7 {% A9 k& w
}   要运行该剧本,需要输入:
( ?4 m' h: t+ [% D; U2 {% ^  groovy restoreAirports.groovy airports.xml   切记,对于要工作的表之间的关系而言,关系的一 的方面的主键字段必然要与关系的多 的方面的外键字段相匹配。例如,储存于 airport 表的 id 列中的值必然要与 flight 表的 arrival_airline_id 列中的值不异。
. E" H) e' x1 H2 w* H  为了确保自动编号的 id 字段被恢复为不异的值,必然要在恢复表前将它们全数删除。这样就可以不才次启动 Grails 年夜头建树表时将自动编号重置为 0。
: p% r7 v5 K* w  将机场数据平安地备份之后(概略其他表中的数据也已经平安备份了),那么此刻您就可以起头试验一些新的 “遗留” 数据了。不懂么?看完下一小节您就会年夜白了。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-9-27 21:10 , Processed in 0.570656 second(s), 32 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表