a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 280|回复: 5

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

[复制链接]
发表于 2012-8-4 12:44:44 | 显示全部楼层 |阅读模式
该示例实现的功能是质数判断,程序实现的功能为客户端程序接收用户输入的数字,然后将用户输入的内容发送给服务器端,服务器端判断客户端发送的数字是否是质数,并将判断的结果反馈给客户端,客户端根据服务器端的反馈显示判断结果。& t$ y3 E" z( F3 q8 |3 f! v
    质数的规则是:最小的质数是2,只能被1和自身整除的自然数。当用户输入小于2的数字,以及输入的内容不是自然数时,都属于非法输入。5 k: P' Z' c" ^. n1 G2 P
    网络程序的功能都分为客户端程序和服务器端程序实现,下面先描述一下每个程序分别实现的功能:
9 S4 H8 f1 n) T" k- }$ y    1、  客户端程序功能:2 s$ @: w: L- u) ]  n
    a)         接收用户控制台输入
+ y3 E7 @; {) R* _' i9 m2 H    b)         判断输入内容是否合法
# {0 _( E" K+ X% s* [/ g9 \3 W    c)         按照协议格式生成发送数据
2 P+ ~+ x- u: o    d)         发送数据, b" g' i: g) q3 X7 l" w
    e)         接收服务器端反馈$ f  d  a) q3 l, @6 e" X0 f- ?; f
    f)          解析服务器端反馈信息,并输出- }5 s; P' Q: n( d" V) x# X
    2、  服务器端程序功能:
! |, ^1 v) W; Q; c    a)         接收客户端发送数据
" _. ~' W5 e. }; R8 n    b)         按照协议格式解析数据9 q6 `* ^9 y, l1 E/ o
    c)         判断数字是否是质数# t5 |& Z; K: M. w
    d)         根据判断结果,生成协议数据
0 Y+ u! e0 _+ U: S: J) b/ B    e)         将数据反馈给客户端. I- L3 U; f4 e9 R! Q' v  c/ k
    分解好了网络程序的功能以后,就可以设计网络协议格式了,如果该程序的功能比较简单,所以设计出的协议格式也不复杂。2 P+ U6 I7 X, x+ m4 z
    客户端发送协议格式:
1 E: q7 H3 ~0 O    将用户输入的数字转换为字符串,再将字符串转换为byte数组即可。8 t, i; |7 Z; P0 R# V* f6 X
    例如用户输入16,则转换为字符串“16”,使用getBytes转换为byte数组。, A4 g2 t, U1 _3 v. [9 i! ^' W5 }
    客户端发送“quit”字符串代表结束连接
: t; [4 y! Z" X) I0 U- u    服务器端发送协议格式:
4 x8 i2 R9 `% N) ^- b9 C/ [    反馈数据长度为1个字节。数字0代表是质数,1代表不是质数,2代表协议格式错误。( P3 `9 u1 I9 A" m8 q2 w- d) O) P4 \
    例如客户端发送数字12,则反馈1,发送13则反馈0,发送0则反馈2。
8 E: g; W/ b, A6 a- M- u    功能设计完成以后,就可以分别进行客户端和服务器端程序的编写了,在编写完成以后联合起来进行调试即可。
4 C* E! m% B6 L+ {- w% X    下面分别以TCP方式和UDP方式实现该程序,注意其实现上的差异。不管使用哪种方式实现,客户端都可以多次输入数据进行判断。对于UDP方式来说,不需要向服务器端发送quit字符串。
回复

使用道具 举报

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

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

以TCP方式实现的客户端程序代码如下:9 e0 Z  Q' X9 A( f4 R6 m
    package example1;
1 N$ N" H: U1 z7 G    import java.io.*;: y; V1 m' b3 D% V* S1 i
    import java.net.*;* e' C' L: V6 [- |9 r6 ^) r
    /**
' E' V8 s* }1 H% e    * 以TCP方式实现的质数判断客户端程序# \+ _( Q* c- q& r3 ^' F
    */8 M* @5 m# W/ L7 u
    public class TCPPrimeClient {
% t/ s; S4 D2 A5 i0 D    static BufferedReader br;
# Q9 {) k4 D+ C1 N    static Socket socket;' y6 R" n9 t7 R: N7 A  c
    static InputStream is;7 c2 {6 o4 \+ b# n; y, b
    static OutputStream os;; Y6 ^! k) W7 H7 S
    /**服务器IP*/$ Q3 R, B8 f* _
    final static String HOST = "127.0.0.1";5 x6 X6 K* ^- {: ]; C
    /**服务器端端口*/
/ g& ]/ I5 ?3 y/ v: A- U0 K7 `/ O    final static int PORT = 10005;
& H. k( t  g: Y& R  R    public static void main(String[] args) {
) k7 H" d& W6 ^6 J0 J: ?4 F6 c    init(); //初始化) ?. I9 T& Z/ E0 T( z+ E. g9 Q
    while(true){
7 P8 W- [! s0 [- q5 `    System.out.println("请输入数字:");1 C6 [+ Y2 ~/ B$ j2 C# }- G: }
    String input = readInput(); //读取输入6 X: O( m6 w- E8 w; {& t
    if(isQuit(input)){ //判读是否结束9 w8 T9 y$ {/ w& h
    byte[] b = "quit".getBytes();
" {4 e0 c# r: g' Z! F0 p/ i    send(b);/ d; e1 e: E: M9 }, {' ?
    break; //结束程序
8 @$ }, u( i; v    }
' ]; r; m0 d1 G% u& k' o" c    if(checkInput(input)){ //校验合法
: z, I2 e  t2 O2 o7 u    //发送数据
0 _& n2 b4 T7 @* J7 m4 j    send(input.getBytes());
( L4 y8 C& v  o5 G( S0 q" R    //接收数据( s) l# o! C3 _7 j$ j; ^
    byte[] data = receive();
1 Z+ U9 @6 [/ v    //解析反馈数据
4 ~0 p8 V) U* ?$ i4 x- M    parse(data);( T; [0 Q) A3 p2 i' F7 T) w- D
    }else{
1 Q7 J0 `4 h- S5 [    System.out.println("输入不合法,请重新输入!");2 t1 ]( i7 Q5 ~) ^7 N
    }$ t: B4 O$ l( h: D  p; ^
    }
( w4 a. @1 g2 {" \    close();  //关闭流和连接8 c1 y$ Y7 {! {  i
    }
. x* w+ K8 }- W    /**0 n' Z! R: V: ~6 q
    * 初始化( |/ o" `& o( Q! ^; u  {2 j6 c. u
    */- b" U8 m3 l5 e5 c1 h; a& B. g. T7 z
    private static void init(){
+ D8 L6 V& }: M1 X4 ]    try {
( E1 x% B$ i/ A6 B    br = new BufferedReader(! y: d2 A5 W3 |6 r$ T2 }
    new InputStreamReader(System.in));
5 W3 ~  j, |" t: l" H( b5 T$ ?! d    socket = new Socket(HOST,PORT);& ^" u) t* V/ Q8 D
    is = socket.getInputStream();& K. R1 C9 t; X: [# a9 G3 N
    os = socket.getOutputStream();% s1 D' ?1 M5 M& q5 C
    } catch (Exception e) {}3 F: _. _% g7 ?# T' x  D
    }' }3 t2 }; J& {. M) s& H
    /**
4 I0 M$ ^8 Q* l! X    * 读取客户端输入" _) p5 ^% H0 C
    */
2 b6 _8 G0 R, M# H# P5 w# Q2 U    private static String readInput(){9 h, k9 K& T( }6 u3 [; ?: `  L
    try {
7 M+ V! R, K% P% Z8 _    return br.readLine();
* k  k* Z( `" u    } catch (Exception e) {
9 O7 l2 Y- o- y( E    return null;" p4 t! h( H1 m4 I7 X0 Y# s% h
    }& q. N# X2 Q" u% H% E9 f! t
    }
% V7 t+ y# z( n1 @0 K2 ^    /**/ s6 |9 X$ t" K1 v
    * 判断是否输入quit. e' C7 Q6 d: c: G& b9 l0 B
    * @param input 输入内容- z  y0 O6 b1 P& I8 F* z- ~# t
    * @return true代表结束,false代表不结束8 O: j4 s: E; Q  N5 O9 q$ x! n& ^
    */
回复 支持 反对

使用道具 举报

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

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

private static boolean isQuit(String input){
( [' D" r- D0 }5 H, t8 Z4 F    if(input == null){0 q" B9 G7 V5 Q! |
    return false;* Y5 Q% f: a0 B* Y% d) G5 N
    }else{# l) |9 P% w2 j2 [
    if("quit".equalsIgnoreCase(input)){
& l/ y# R6 ~( k+ |4 k+ {3 k* B    return true;* E5 C( C2 _- {
    }else{
& D' e- M& d4 s    return false;
+ u8 _( M5 {) ?, U  N( `; N    }6 B* V! d( j9 w$ Y3 T
    }
" G) d5 c2 o; C* M( _7 j    }
; Q- c) i0 ]6 ?& n    /**: K8 K0 f( M8 ]8 |* D
    * 校验输入& g; s4 e9 w5 o* a
    * @param input 用户输入内容
) d- S# N* d. P! Q: m3 m    * @return true代表输入符合要求,false代表不符合
$ |  Z( [9 A7 w    */
- C/ N' _+ p, w" K4 p/ z! F    private static boolean checkInput(String input){: @: ]6 m! U: Z! h
    if(input == null){1 c) ^" C9 l5 L+ M7 u! z  D0 `, A4 T
    return false;
( E% E4 x9 H0 T    }
7 B4 U' k7 K2 H, _8 V& w    try{1 `: Q( y. {, Y
    int n = Integer.parseInt(input);6 a% C8 K2 X2 b, k
    if(n >= 2){1 |- N9 P" G- h1 d# b2 P
    return true;
( B9 Z! f3 J% M' M8 A6 e    }else{& r0 G. Y9 f0 j) T% C
    return false;% r# b- E: c0 A
    }
  ~6 J( M& ?5 I4 x( [6 D4 R    }catch(Exception e){
* O7 d% ^5 b# Q& X  `    return false;  //输入不是整数
$ h- g, c: D3 t% R7 l    }$ i& l6 J5 x" o7 u1 @
    }) Z8 X- H. {: U/ s  o
    /**; |7 e" N" l  ]; e/ R
    * 向服务器端发送数据$ X  M( [$ p2 _* H8 v% K/ w
    * @param data 数据内容0 ?8 Q% c* R0 G+ L
    */- x& f# O  |8 w3 `! `6 u/ [) ?
    private static void send(byte[] data){
7 ~5 ]. `5 P- j    try{3 K8 }8 }4 l" g1 w/ ~
    os.write(data);2 s( a& K+ ^0 F, b! |9 Q% r& q
    }catch(Exception e){}2 [* G- {& z. g9 M' r# }+ K5 f  |
    }
6 D  _# h6 Z( R% W. ^" v3 T+ }    /**. m2 r' a1 P1 |: ?$ S1 |0 c* D7 j
    * 接收服务器端反馈
* Z+ J1 R( n9 n' c/ y. V    * @return 反馈数据9 S! c  s! \+ z7 F! G
    */
7 d# X% ]" E! {6 Z, b7 z% _    private static byte[] receive(){+ }1 a! q# q% j
    byte[] b = new byte[1024];  b5 ]3 {7 M, U' I- S$ F2 a( ~
    try {2 {! Z. H* r( N1 U: x% s5 `' v
    int n = is.read(b);
! V& @9 [/ e% r2 i5 t    byte[] data = new byte[n];% e( R/ H9 b! _8 K9 s5 I1 j
    //复制有效数据
5 x/ b6 ]$ @& r- U& F    System.arraycopy(b, 0, data, 0, n);# a2 B+ T2 Q/ H4 r9 F% A
    return data;
3 |" S; s7 a5 i4 [4 Z* X( h    } catch (Exception e){}6 H: I' u% S9 r3 B. |
    return null;3 P6 R3 G( h- N; ~8 ]
    }
, m" v/ }2 k2 I    /**
回复 支持 反对

使用道具 举报

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

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

* 解析协议数据
4 T" _: t5 t4 G    * @param data 协议数据4 X- w) L+ F% p, p& G9 `
    */
1 b: H. W+ c- G4 q- r4 D    private static void parse(byte[] data){  M! k$ \- r/ Y' T
    if(data == null){! p3 _( F' k+ i6 Z7 E$ `0 r
    System.out.println("服务器端反馈数据不正确!");
0 K2 a, }1 J: P" H+ x0 ], `    return;
' k2 P5 I: q+ J2 j$ ^4 `! r3 W- y    }
9 ^# q$ F; _  {' x, w    byte value = data[0]; //取第一个byte
/ R8 h) u  |+ k- u! X$ d    //按照协议格式解析' a% a0 j' y/ r3 [$ V
    switch(value){
3 w9 c& _8 e8 n+ ]  j# B    case 0:
+ Z% y" j; t4 q) [# V- f* W    System.out.println("质数");& A6 x& v! z: n' x- M- ]. v1 n
    break;
/ O; O( ]  Q4 n, d' o5 r; h    case 1:
  K  H0 S" J8 f3 ]( C$ v6 s    System.out.println("不是质数");. D) _8 I5 n) @% f
    break;
) Z1 N- c4 q8 D4 H  P! ~& p) j    case 2:4 B" g" r# a  Q
    System.out.println("协议格式错误");% }/ u" i, X. Y- j! O
    break;
) L8 Q9 b; @7 r9 X) }1 T    }
: L, v2 m/ u, i4 L    }
) S) n' L7 G( E) J% W2 y    /**
9 \) |5 y, N& @' F/ |6 z9 p    * 关闭流和连接; B: l4 l2 g1 t( \% u
    */1 o; u% X* f! [2 z3 x0 n# r
    private static void close(){
5 K4 n, ?+ |% a# S, M* \    try{; o: W& m: }6 \9 V( X: O- h
    br.close();
* q6 V, O1 ^" V    is.close();
. ?2 Y- d! a+ W, F: D7 a; G    os.close();
; d. ^* V' r$ Q6 ^+ `( D/ d    socket.close();( ]+ }1 F# F) a$ ^! V" G% T
    }catch(Exception e){6 Q/ q* T0 h! T, S9 }6 i/ H
    e.printStackTrace();
* c3 U) j: v2 I- N: P( Z    }/ s  O: `; ]  {
    }
8 l, r8 M4 n) d    }
回复 支持 反对

使用道具 举报

 楼主| 发表于 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 文档。" ~3 L0 T' a/ u! U: I! P
  最后一条语句(以 x.airports 开首)建树了 XML 树。XML 文档的根元素为 airports。它还为数据库的每一行建树了一个 airport 元素,该元素带有 id 属性。嵌套于 airport 元素的元素有 version、name 和 city 元素(想体味更多关于 Groovy Sql 和 MarkupBuilder 用途的信息,参见 参考资料)。$ J& V+ B3 }: K6 u/ i
  清单 2 展示了由此获得的 XML:
; D( S' B$ O& U! i8 |' _3 W  清单 2. 来自备份剧本的 XML 输出
' a: r! W& J* F6 l: R. _+ d8 n' m# `
+ Q. [, S6 H# l  e  
( H! F( R4 G% y% l, ?( Y/ `: `5 U    2; F5 ?8 r$ I$ K5 p8 [2 r0 t
    Denver International Airport- \/ R( W3 A6 p& `4 ^
    Denver
4 s! H6 T  h; j* H9 u    CO
  i# T$ E$ X: \    US6 H! a+ T: \" Z
    den5 d& N/ r6 a' }! I
    39.85831882 c6 P( w" r  X4 r% J- j' N1 E" O
    -104.6674674' J* S+ Q6 |  I% G& }
  - C/ h8 A( B( t9 ]: X* t( T
  ...
5 I1 q9 i" X/ z  ...& l0 k4 ~% m6 f, O
  在备份剧本中,必然要按照主键挨次拖出记实。当恢复这个数据时,必然要按不异的挨次插入值,以确奔窃攸值同样匹配(关于这一点我将不才一小节进一步胪陈)。  注重,该剧本是完全自力于 Grails 框架的。要使用它,就必然要在您的系统上安装 Groovy(参见 参考资料,查找下载与安装声名)。此外,类路径中必然要有 JDBC 驱动轨范 JAR。可以在运行剧本时进行指定。在 UNIX&reg; 中,要输入:
4 r4 {9 s$ M. K# m$ K  groovy -classpath /path/to/mysql.jar:. backupAirports.groovy   当然了,在 Windows&reg; 上,响应的文件路径和 JAR 分隔符是分歧的。在 Windows 中,则需要输入:
: d$ j3 [* A1 W2 F5 ~6 ]* @  groovy -classpath c:pathtomysql.jar;. backupAirports.groovy   因为我经常使用 MySQL,所以我将一份该 JAR 的副本保留在了我的主目录(在 UNIX 上为 /Users/sdavis,在 Windows 上为 c:Documents and Settingssdavis)中的 .groovy/lib 目录中。昔时夜呼吁走运行 Groovy 剧本时,该目录中的 JAR 会自动包含在类路径中。, {+ c. X+ v" n+ g0 t8 i
  清单 1 中的剧本将输出写到了屏幕。要将数据保留在一个文件中,可以在运行剧本时重定向输出:
  z) n. x( [6 }' f  groovy backupAirports.groovy > airports.xml   恢复数据# Z/ a& z- n: Z
7 l, c/ v# U9 k2 ~9 C" [: A
  年夜数据库中获掏出数据仅仅是成功了一半。还要再将数据恢复到数据库中。清单 3 中展示的 restoreAirports.groovy 剧本用 Groovy XmlParser 读入了 XML,机关了一个 SQL insert 语句,并用了一个 Groovy SQL 对象来执行该语句(要体味更多关于 XmlParser的信息,参见 参考资料)。
回复 支持 反对

使用道具 举报

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

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

</p>  清单 3. 年夜 XML 中恢复数据库记实的 Groovy 剧本! n( `- J% u( f# s
if(args.size()){
, I, q3 q% j& ^' C   f = new File(args[0])! \# x7 M- z0 Q. w$ i' n
   println f
; G& Z( w* d# N4 x9 o
$ K3 T, j: d4 o/ z2 ]. P: g   sql = groovy.sql.Sql.newInstance(- H1 Q7 m9 j1 V% g8 L0 e2 t
      "jdbc:mysql://localhost/aboutgroovy?autoReconnect=true",  M' U0 q* v/ Z  E6 c' u
      "grails",! T" K: M$ n; o- R$ Y' W/ J
      "server",
0 m% ~9 f# F* P6 B8 W, W) @6 J/ R      "com.mysql.jdbc.Driver")& V* u: a- _* A6 W* o& u

5 x3 X* h+ {" l" L% t) g   items = new groovy.util.XmlParser().parse(f)3 U0 Q% r1 [3 ^0 v8 j1 W
   items.item.each{item ->% Y6 R5 g5 C1 S4 O* p0 N
     println "${item.@id} -- ${item.title.text()}"/ S9 S: L& p* Y3 b8 f7 a4 U' W
      sql.execute(% f4 f7 {0 m  D: d# `
         "insert into item (version, title, short_description, description,
& W9 X& ~0 U$ m9 T0 _' g6 T                 url, type, date_posted, posted_by) values(?,?,?,?,?,?,?,?)",- U- A  Z* H7 i  e0 I# R7 w" f  c
         [0, item.title.text(), item.shortDescription.text(), item.description.text(),
6 u, p4 y  |( j* z  S2 f             item.url.text(), item.type.text(), item.datePosted.text(), 6 P# ~; W. F6 N3 L: h
             item.postedBy.text()]
5 L% [% A, `. P: J  a         )6 |7 R. U5 [& j# O, R' Z
   }
3 B" ^$ q; r5 d; V  @3 F}
' y+ @, T3 ?$ Z3 l& D) U5 g$ Ielse{$ ]# t2 J! D) O; F6 f, J8 P
   println "USAGE: itemsRestore [filename]"( D' R7 Z1 Z. d
}   要运行该剧本,需要输入:
$ d& k6 E: c6 z; k/ Y0 _# [  groovy restoreAirports.groovy airports.xml   切记,对于要工作的表之间的关系而言,关系的一 的方面的主键字段必然要与关系的多 的方面的外键字段相匹配。例如,储存于 airport 表的 id 列中的值必然要与 flight 表的 arrival_airline_id 列中的值不异。2 B* e* }% z/ l. H6 h' l
  为了确保自动编号的 id 字段被恢复为不异的值,必然要在恢复表前将它们全数删除。这样就可以不才次启动 Grails 年夜头建树表时将自动编号重置为 0。
* H% u6 Q2 {2 m' z% k2 l  将机场数据平安地备份之后(概略其他表中的数据也已经平安备份了),那么此刻您就可以起头试验一些新的 “遗留” 数据了。不懂么?看完下一小节您就会年夜白了。
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-7 03:35 , Processed in 0.239716 second(s), 31 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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