客户端
package client;
import server.Server;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Scanner;
public class Cilent {
public static void main(String[] args) throws IOException {
Socket sk = new Socket(InetAddress.getLocalHost(), 10261);
InputStream is = sk.getInputStream();
OutputStream os = sk.getOutputStream();
//发送数据
byte[] bytes = new byte[1024];
int len;
//获取输出,输出流
Scanner sc = new Scanner(System.in);
System.out.println("请选择选项 1 进入聊天室 2 传送文件到服务端 3 退出");
String nextInt = sc.nextLine();
//进入聊天室
if (nextInt.equals("1")) {
System.out.println("系统:请输入用户名");
String name = sc.nextLine();
System.out.println("系统:请输入密码");
String password = sc.nextLine();
os.write(name.getBytes());
os.write(password.getBytes());
//获取服务器返回结果信息
bytes=new byte[1024];
len=is.read(bytes);
String result = new String(bytes, 0, len);
System.out.println("result = " + result);
if (result.contains("成功")) {
while (true) {
System.out.println("系统:请发送消息给服务端" + new Date());
String outmessage = sc.nextLine();
os.write(outmessage.getBytes());
if (outmessage.contains("退出")) {
//退出
os.write("退出聊天".getBytes());
break;
}
//获取服务器返回的消息
System.out.println("等待服务器返回消息");
bytes=new byte[1024];
len=is.read(bytes);
String inString = new String(bytes, 0, len);
System.out.println("接受的服务器消息 : "+inString);
}
}else {
sk.close();
return;
}
}else {
//todo
//通知服务器减少一个连接,报错
Server.num.decrementAndGet();
sk.close();
}
}
}
服务端
package server;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Server {
private static ServerSocket ss;
public static AtomicInteger num=new AtomicInteger(1);
static {
//创建服务端程序
System.out.println("服务端套接字对象创建");
try {
ss = new ServerSocket(10261);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//使用线程池,支持多个客户端连接
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
10,
20,
24,
TimeUnit.HOURS,
new ArrayBlockingQueue<>(100),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
//开启10个线程
// while (threadPoolExecutor.getActiveCount() < 10) {
// //提交任务
// threadPoolExecutor.submit(new Task(ss));
// }
threadPoolExecutor.submit(()->{
while (true) {
try {
Thread.sleep(5000);
System.out.println();
System.out.println("-------------");
System.out.println("当前客户端连接数" + (num.get() - 1));
System.out.println("-------------");
System.out.println();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
while (true){
if (threadPoolExecutor.getActiveCount()<=num.get()){
threadPoolExecutor.submit(new Task(ss));
}
}
}
}
任务类
package server;
import bean.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import util.JDBCUtils;
import javax.xml.crypto.Data;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.Scanner;
public class Task implements Runnable {
private ServerSocket ss;
private User query=null;
private Connection conn = null;
public Task(ServerSocket ss) {
this.ss = ss;
}
@Override
public void run() {
InputStream is=null;
OutputStream os=null;
Scanner sc=new Scanner(System.in);
//绑定客户端
Socket accept=null;
try {
accept = ss.accept();
Server.num.incrementAndGet();
System.out.println("accept = " + accept);
} catch (IOException e) {
e.printStackTrace();
System.out.println("绑定客户端出错");
}
//获取客户端信息
InetAddress inetAddress = accept.getInetAddress();
String hostName = inetAddress.getHostName();
String hostAddress = inetAddress.getHostAddress();
//获取输入流
try {
is = accept.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
//读取数据
byte[] bytes=new byte[1024];
int len = 0;
//获取登录的用户名
try {
len=is.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
String name = new String(bytes,0,len);
//获取登录的密码
//二次获取输入流
try {
is = accept.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
len=is.read(bytes);
} catch (IOException e) {
e.printStackTrace();
}
String password = new String(bytes,0,len);
boolean check = check(name, password);
//写回结果
try {
os= accept.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
if (check){
try {
os.write(("登录成功,欢迎"+name+" 你当前IP + "+hostAddress).getBytes());
//获取客户端发送的消息
while (true){
len=is.read(bytes);
String inmessage = new String(bytes, 0, len);
if (inmessage.contains("退出")){
break;
}
String now = LocalDateTime.now().toString();
System.out.println("收到消息 : "+inmessage+" @@ 用户 "+name+" 消息,请回复!!"+" 当前时间: "+now);
System.out.print("回复: " + name + " : ");
//写回消息
String outmessage = sc.nextLine();
os.write(outmessage.getBytes());
System.out.println("消息回复成功!!"+" 当前时间: "+now);
//保存到服务器
saveMessage(query.getId(),inmessage,outmessage,now);
System.out.println("聊天记录保存成功!");
}
//聊天结束,断开连接
System.out.println(Thread.currentThread().getName()+"--退出");
accept.close();
Server.num.decrementAndGet();
return;
} catch (IOException e) {
e.printStackTrace();
}finally {
JDBCUtils.closeSource(conn,null);
}
}else {
try {
os.write(("登录失败,账户或者密码错误!").getBytes());
//断开连接,结束线程
accept.close();
System.out.println(Thread.currentThread().getName()+"--退出");
Server.num.decrementAndGet();
return;
} catch (IOException e) {
e.printStackTrace();
}
}
}
//判断用户名和密码是否正确
public boolean check(String name,String password) {
System.out.println("select * from user where name = "+name+" and password = "+password);
//获取连接
conn = JDBCUtils.getConnection();
//使用DBUtil
try {
query = new QueryRunner().query(
conn,
"select * from user where name = ? and password = ?",
new BeanHandler<User>(User.class),
name,
password
);
} catch (SQLException e) {
e.printStackTrace();
System.out.println("服务端验证账户和密码时出错");
//关闭资源
JDBCUtils.closeSource(conn,null);
return false;
}
System.out.println("query = " + query);
if (query!=null){
return true;
}else {
//关闭资源
JDBCUtils.closeSource(conn,null);
return false;
}
}
//保存消息记录
public void saveMessage(int id,String inMessage,String outMessage,String data){
try {
int update = new QueryRunner().update(
conn,
"insert into chat_history values (null,?,?,?,?)",
id,
inMessage,
outMessage,
data
);
if (update!=1){
System.out.println("保存聊天记录出错");
}
} catch (SQLException e) {
e.printStackTrace();
System.out.println("保存聊天记录出错");
}
}
}