Java编程那些事儿109——网络编程示例2
副标题#e#
13.3.2 猜数字小游戏
下面这个示例是一个猜数字的节制台小游戏。该游戏的法则是:当客户端第一次毗连随处事器端时,处事器端出产一个「0,50」之间的随机数字,然后客户端输入数字来猜该数字,每次客户端输入数字今后,发送给处事器端,处事器端判定该客户端发送的数字和随机数字的干系,并反馈较量功效,客户端总共有5次猜的时机,猜中时提示猜中,当输入“quit”时竣事措施。
和前面的示例雷同,在举办网络措施开拓时,首先需要解析一下成果的实现,以为成果是在客户端措施中实现照旧在处事器端措施中实现。区分的法则一般是:客户端措施实现吸收用户输入等界面成果,并实现一些基本的校验低落处事器端的压力,而将措施焦点的逻辑以及数据存储等成果放在处事器端举办实现。遵循该原则分另外客户端和处事器端成果如下所示。
客户端措施成果列表:
1、吸收用户节制台输入
2、判定输入内容是否正当
3、凭据协议名目发送数据
4、按照处事器端的反馈给出相应提示
处事器端措施成果列表:
1、吸收客户端发送数据
2、凭据协议名目理会数据
3、判定发送过来的数字和随机数字的干系
4、按照判定功效出产协议数据
5、将出产的数据反馈给客户端
在该示例中,实际利用的网络呼吁也只有两条,所以显得协议的名目较量简朴。
个中客户端措施协议名目如下:
1、将用户输入的数字转换为字符串,然后转换为byte数组
2、发送“quit”字符串代表退出
#p#副标题#e#
个中处事器端措施协议名目如下:
1、反馈长度为1个字节,数字0代表相等(猜中),1代表大了,2代表小了,其它数字代表错误。
实现该措施的代码较量多,下面分为客户端措施实现和处事器端措施实现别离进队罗列。
客户端措施实现代码如下:
package guess;
import java.net.*;
import java.io.*;
/**
* 猜数字客户端
*/
public class TCPClient {
public static void main(String[] args) {
Socket socket = null;
OutputStream os = null;
InputStream is = null;
BufferedReader br = null;
byte[] data = new byte[2];
try{
//成立毗连
socket = new Socket(
"127.0.0.1",10001);
//发送数据
os= socket.getOutputStream();
//读取反馈数据
is = socket.getInputStream();
//键盘输入流
br = new BufferedReader(
new InputStreamReader(System.in));
//多次输入
while(true){
System.out.println("请输入数字:");
//吸收输入
String s = br.readLine();
//竣事条件
if(s.equals("quit")){
os.write("quit".getBytes());
break;
}
//校验输入是否正当
boolean b = true;
try{
Integer.parseInt(s);
}catch(Exception e){
b = false;
}
if(b){ //输入正当
//发送数据
os.write(s.getBytes());
//吸收反馈
is.read(data);
//判定
switch(data[0]){
case 0:
System.out.println("相等!祝贺你!");
break;
case 1:
System.out.println("大了!");
break;
case 2:
System.out.println("小了!");
break;
default:
System.out.println("其它错误!");
}
//提示猜的次数
System.out.println("你已经猜了" + data[1] + "次!");
//判定次数是否到达5次
if(data[1] >= 5){
System.out.println("你挂了!");
//给处事器端线程封锁的时机
os.write("quit".getBytes());
//竣事客户端措施
break;
}
}else{ //输入错误
System.out.println("输入错误!");
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
//封锁毗连
br.close();
is.close();
os.close();
socket.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
}
在该示例中,首先成立一个到IP地点为127.0.0.1的端口为10001的毗连,然后举办各个流的初始化事情,将逻辑节制的代码放入在一个while轮回中,这样可以在客户端多次举办输入。在轮回内部,首先判定用户输入的是否为quit字符串,假如是则竣事措施,假如输入不是quit,则首先校验输入的是否是数字,假如不是数字则直接输出“输入错误!”并继承吸收用户输入,假如是数字则发送给处事器端,并按照处事器端的反馈显示相应的提示信息。最后封锁流和毗连,竣事客户端措施。
处事器端措施的实现照旧分为处事器节制措施和逻辑线程,实现的代码别离如下:
#p#分页标题#e#
package guess;
import java.net.*;
/**
* TCP毗连方法的处事器端
* 实现成果:吸收客户端的数据,判定数字干系
*/
public class TCPServer {
public static void main(String[] args) {
try{
//监听端口
ServerSocket ss = new ServerSocket(10001);
System.out.println("处事器已启动:");
//逻辑处理惩罚
while(true){
//得到毗连
Socket s = ss.accept();
//启动线程处理惩罚
new LogicThread(s);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
package guess;
import java.net.*;
import java.io.*;
import java.util.*;
/**
* 逻辑处理惩罚线程
*/
public class LogicThread extends Thread {
Socket s;
static Random r = new Random();
public LogicThread(Socket s){
this.s = s;
start(); //启动线程
}
public void run(){
//生成一个[0,50]的随机数
int randomNumber = Math.abs(r.nextInt() % 51);
//用户猜的次数
int guessNumber = 0;
InputStream is = null;
OutputStream os = null;
byte[] data = new byte[2];
try{
//得到输入流
is = s.getInputStream();
//得到输出流
os = s.getOutputStream();
while(true){ //多次处理惩罚
//读取客户端发送的数据
byte[] b = new byte[1024];
int n = is.read(b);
String send = new String(b,0,n);
//竣事鉴别
if(send.equals("quit")){
break;
}
//理会、判定
try{
int num = Integer.parseInt(send);
//处理惩罚
guessNumber++; //猜的次数增加1
data[1] = (byte)guessNumber;
//判定
if(num > randomNumber){
data[0] = 1;
}else if(num < randomNumber){
data[0] = 2;
}else{
data[0] = 0;
//假如猜对
guessNumber = 0; //清零
randomNumber = Math.abs(r.nextInt() % 51);
}
//反馈给客户端
os.write(data);
}catch(Exception e){ //数据名目错误
data[0] = 3;
data[1] = (byte)guessNumber;
os.write(data); //发送错误标识
break;
}
os.flush(); //强制发送
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
is.close();
os.close();
s.close();
}catch(Exception e){}
}
}
}
在该示例中,处事器端节制部门和前面的示例中一样。也是期待客户端毗连,假如有客户端毗连达到时,则启动新的线程去处理惩罚客户端毗连。在逻辑线程中实现措施的焦点逻辑,首先当线程执行时出产一个随机数字,然后按照客户端发送过来的数据,判定客户端发送数字和随机数字的干系,然后反馈相应的数字的值,并影象客户端已经猜过的次数,当客户端猜中今后清零猜过的次数,使得客户端措施可以继承举办游戏。
总体来说,该措施示例的布局以及成果都与上一个措施较量雷同,但愿通过较量这两个措施,加深对付网络编程的认识,早日步入网络编程的大门。