一、知识点概括
1.输入输出流
2.网络编程
3.反射
4.JDK8
二、案例分析
创建一个多线程的TCP服务器以及客户端,完成下面的功能:客户端选择功能,进行注册或登录。 服务端:读入客户端发给服务器端的字符串, 在指定文件中进行查找,判断是否存在,并将结果返回给用户;如果用户进行注册,则将用户录入信息保存到指定文件中。
import java.util.Scanner;
public class StartMenu {
public static void main(String[] args) {
Client client = new Client();
System.out.println("------欢迎进入图书借阅系统------");
Scanner sc = new Scanner(System.in);
int choice=0;
do {
System.out.println("请输入您的选择:1.注册 2.登录0.退出");
choice = sc.nextInt();
switch(choice) {
case 1:
client.reg();
//多线程 竞争了
break;
case 2:
System.out.println("暂未开发!");
default:
break;
}
}while(choice!=0);//退出
System.out.println("欢迎下次再来");
}
}
/*
* 启动服务
*/
public class StartServer {
public static void main(String[] args) {
Server server = new Server();
server.registerUser();
}
}
/*
* 服务器对象
* 注册
* 登录 userPros.properties
* 把注册任务、登录任务给两个线程去做
*/
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
public class Server {
//服务端持有properties文件
private Properties userPros;
public Server(){
//用于存储properties文件内容的
userPros = new Properties();
File file = new File("userPros.properties");
if(file.exists()) {
try {
//是把外部文件加载到userPros对象中
userPros.load(new FileReader(file));
} catch (Exception e) {
System.out.println("加载文件失败!");
}
}
}
//注册
public void registerUser() {
try {
//1.创建服务端
ServerSocket server = new ServerSocket(666);
System.out.println("注册线程已启动");
while(true) {
//2.接收客户端
Socket client = server.accept();
//3.将客户端对象和配置文件传给注册线程
new RegThread(client,userPros).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.Properties;
public class LoginThread extends Thread{
private Socket client;
private Properties userPros;
public LoginThread(Socket client,Properties userPros) {
this.client = client;
this.userPros = userPros;
}
@Override
public void run() {
try {
//1.获得输入输出流
InputStream is = client.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
BufferedReader br = new BufferedReader(isr);
OutputStream os = client.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
PrintWriter pw = new PrintWriter(osw);
//2.接收客户端输入的用户名和密码
String userinfo = br.readLine();
String[] users = userinfo.split("#");
String username = users[0];
String password = users[1];
//3.验证
if(userPros.containsKey(username)) {//用户名存在
if(userPros.getProperty(username).equals(password)) {
pw.println("登录成功。。");
pw.flush();
}else {
pw.println("登录失败。。密码输入错误");
pw.flush();
}
}else {
pw.println("登录失败,账号不存在!");
pw.flush();
}
//4.关闭资源
pw.close();
br.close();
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Properties;
public class RegThread extends Thread {
//客户端
private Socket client;
//配置文件
private Properties userPros;
public RegThread(Socket client,Properties userPros) {
this.client = client;
this.userPros = userPros;
}
//线程任务--做注册
public void run() {
try {
//1.获得输入输出流
InputStream is = client.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
BufferedReader br = new BufferedReader(isr);
OutputStream os = client.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
PrintWriter pw = new PrintWriter(osw);
//2.获得用户提交的数据 zhangsan#123
String userinfo = br.readLine();
String[] users = userinfo.split("#");
String username = users[0];
String password = users[1];
//3.判断用户名是否存在!
if(userPros.containsKey(username)) {
pw.println("用户已存在!请重新输入....");
pw.flush();
}else {
//4.如果不存在,应该做保存!并告知当前客户端,注册成功
//存到集合对象里
userPros.setProperty(username, password);
//存到硬盘的文件里
userPros.store(new FileWriter("userPros.properties"),null);
pw.println("注册成功...");
pw.flush();
}
//5.关闭资源
pw.close();
br.close();
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*
* 注册
* 登录
*
*/
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.xml.ws.handler.MessageContext.Scope;
public class Client {
public void reg() {
try {
//1.链接服务端
Socket client = new Socket("192.168.8.145",666);
//2.把客户端传给线程
ClientRegThread crt = new ClientRegThread(client);
//3.启动线程
crt.start();
//4.为了避免主线程先执行
crt.join();
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientLoginThread extends Thread {
private Socket client;
public ClientLoginThread(Socket client) {
this.client = client;
}
@Override
public void run() {
try {
//1.获得输入输出流
InputStream is = client.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
BufferedReader br = new BufferedReader(isr);
OutputStream os = client.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
PrintWriter pw = new PrintWriter(osw);
//2.用户输入数据,拼接
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.next();
System.out.println("请输入密码:");
String password = sc.next();
String userinfo = username+"#"+password;
//3.提交给服务端
pw.println(userinfo);
pw.flush();
//4.接收响应结果
String msg = br.readLine();
System.out.println(msg);
//5.释放
pw.close();
br.close();
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientRegThread extends Thread {
private Socket client;
public ClientRegThread(Socket client) {
this.client = client;
}
@Override
public void run() {
try {
//1.获得输入输出流
InputStream is = client.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"UTF-8");
BufferedReader br = new BufferedReader(isr);
OutputStream os = client.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os,"UTF-8");
PrintWriter pw = new PrintWriter(osw);
//2.用户输入数据,并拼接整理
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.next();
System.out.println("请输入密码");
String password = sc.next();
String userinfo = username+"#"+password;
//3.提交给服务端
pw.println(userinfo);
pw.flush();
//4.接收服务端的回应
String msg = br.readLine();
System.out.println(msg);
//5.关闭
pw.close();
br.close();
client.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果: