该示例实现的功能是质数判断,程序实现的功能为客户端程序接收用户输入的数字,然后将用户输入的内容发送给服务器端,服务器端判断客户端发送的数字是否是质数,并将判断的结果反馈给客户端,客户端根据服务器端的反馈显示判断结果。
质数的规则是:最小的质数是2,只能被1和自身整除的自然数。当用户输入小于2的数字,以及输入的内容不是自然数时,都属于非法输入。
网络程序的功能都分为客户端程序和服务器端程序实现,下面先描述一下每个程序分别实现的功能:
1、 客户端程序功能:
a) 接收用户控制台输入
b) 判断输入内容是否合法
c) 按照协议格式生成发送数据
d) 发送数据
e) 接收服务器端反馈
f) 解析服务器端反馈信息,并输出
2、 服务器端程序功能:
a) 接收客户端发送数据
b) 按照协议格式解析数据
c) 判断数字是否是质数
d) 根据判断结果,生成协议数据
e) 将数据反馈给客户端
分解好了网络程序的功能以后,就可以设计网络协议格式了,如果该程序的功能比较简单,所以设计出的协议格式也不复杂。
客户端发送协议格式:
将用户输入的数字转换为字符串,再将字符串转换为byte数组即可。
例如用户输入16,则转换为字符串“16”,使用getBytes转换为byte数组。
客户端发送“quit”字符串代表结束连接
服务器端发送协议格式:
反馈数据长度为1个字节。数字0代表是质数,1代表不是质数,2代表协议格式错误。
例如客户端发送数字12,则反馈1,发送13则反馈0,发送0则反馈2。
功能设计完成以后,就可以分别进行客户端和服务器端程序的编写了,在编写完成以后联合起来进行调试即可。
下面分别以TCP方式和UDP方式实现该程序,注意其实现上的差异。不管使用哪种方式实现,客户端都可以多次输入数据进行判断。对于UDP方式来说,不需要向服务器端发送quit字符串。
以TCP方式实现的客户端程序代码如下:
package example1;
import java.io.*;
import java.net.*;
/**
* 以TCP方式实现的质数判断客户端程序
*/
public class TCPPrimeClient {
static BufferedReader br;
static Socket socket;
static InputStream is;
static OutputStream os;
/**服务器IP*/
final static String HOST = "127.0.0.1";
/**服务器端端口*/
final static int PORT = 10005;
public static void main(String[] args) {
init(); //初始化
while(true){
System.out.println("请输入数字:");
String input = readInput(); //读取输入
if(isQuit(input)){ //判读是否结束
byte[] b = "quit".getBytes();
send(b);
break; //结束程序
}
if(checkInput(input)){ //校验合法
//发送数据
send(input.getBytes());
//接收数据
byte[] data = receive();
//解析反馈数据
parse(data);
}else{
System.out.println("输入不合法,请重新输入!");
}
}
close(); //关闭流和连接
}
/**
* 初始化
*/
private static void init(){
try {
br = new BufferedReader(
new InputStreamReader(System.in));
socket = new Socket(HOST,PORT);
is = socket.getInputStream();
os = socket.getOutputStream();
} catch (Exception e) {}
}
/**
* 读取客户端输入
*/
private static String readInput(){
try {
return br.readLine();
} catch (Exception e) {
return null;
}
}
/**
* 判断是否输入quit
* @param input 输入内容
* @return true代表结束,false代表不结束
*/
private static boolean isQuit(String input){
if(input == null){
return false;
}else{
if("quit".equalsIgnoreCase(input)){
return true;
}else{
return false;
}
}
}
/**
* 校验输入
* @param input 用户输入内容
* @return true代表输入符合要求,false代表不符合
*/
private static boolean checkInput(String input){
if(input == null){
return false;
}
try{
int n = Integer.parseInt(input);
if(n >= 2){
return true;
}else{
return false;
}
}catch(Exception e){
return false; //输入不是整数
}
}
/**
* 向服务器端发送数据
* @param data 数据内容
*/
private static void send(byte[] data){
try{
os.write(data);
}catch(Exception e){}
}
/**
* 接收服务器端反馈
* @return 反馈数据
*/
private static byte[] receive(){
byte[] b = new byte[1024];
try {
int n = is.read(b);
byte[] data = new byte[n];
//复制有效数据
System.arraycopy(b, 0, data, 0, n);
return data;
} catch (Exception e){}
return null;
}
/**
* 解析协议数据
* @param data 协议数据
*/
private static void parse(byte[] data){
if(data == null){
System.out.println("服务器端反馈数据不正确!");
return;
}
byte value = data[0]; //取第一个byte
//按照协议格式解析
switch(value){
case 0:
System.out.println("质数");
break;
case 1:
System.out.println("不是质数");
break;
case 2:
System.out.println("协议格式错误");
break;
}
}
/**
* 关闭流和连接
*/
private static void close(){
try{
br.close();
is.close();
os.close();
socket.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
考试大温馨提示:本内容来源于网络,仅代表作者个人观点,与本站立场无关,仅供您学习交流使用。其中可能有部分文章经过多次转载而造成文章内容缺失、错误或文章作者不详等问题,请您谅解。如有侵犯您的权利,请联系我们,本站会立即予以处理。
编辑推荐:
JavaTimer和TimerTask详解
8个改善Java遗留系统的技巧
Java数组之初始化及实例代码