准备工作
检查
这里的hosts配置文件内容一般不用修改。我是因为之前玩tomcat的时候,动过这里,测试的时候一直没有效果,才回过头来检查。
jar包
Java操作mysql数据库的jar包。也可以用其他的数据库,添加对应的jar包即可。
https://mvnrepository.com/artifact/mysql/mysql-connector-java/8.0.28
先下载到本地,之后会用到。
服务器
/**
* @author WuYongheng
* @date 2022/10/11
* @description
*/
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.ArrayList;
class ServerThread extends Thread {
Socket socket;
ArrayList<Socket> lst;
public ServerThread() {
}
public ServerThread(Socket socket, ArrayList<Socket> lst) {
this.socket = socket;
this.lst = lst;
}
public ServerThread(Socket socket) {
this.socket = socket;
}
public void run() {
byte b[] = new byte[300];
try {
// jdbc
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/chat";
Connection conn = DriverManager.getConnection(url, "root", "123456");
Statement st = conn.createStatement();
while (true) {//服务器可以一直收到消息
int len = socket.getInputStream().read(b);
String s = new String(b, 0, len);
String sql = "insert into msginfo (msg) values('" + s + "')";
st.executeUpdate(sql);//调用函数执行insert语句
//将收到的消息想其他客户端发送
for (Socket skt : lst) {
if(skt==socket)//加这一行,自己的客户端就不发了,向其他的客户端发
continue;
skt.getOutputStream().write(b, 0, len);
}
System.out.println(s);
}
// System.out.println(new String(b, 0, len));
} catch (Exception e) {
}
}
}
class Server {
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.out.println("使用方法: java 程序 端口");
return;
}
int port = 0;
try {
port = Integer.parseInt(args[0]);
if (port < 5555 || port > 9999) {
System.err.println("无效的端口,端口必须在5555~9999之间");
return;
}
} catch (Exception e) {
System.err.println("无效的端口,端口必须在5555~9999之间");
return;
}
ServerSocket server = new ServerSocket(port);
ArrayList<Socket> lst = new ArrayList<Socket>();
while (true) {
Socket socket = server.accept();
lst.add(socket);
new ServerThread(socket, lst).start();//socket,lst!!
}
// byte b[] = new byte[300];
// int len = socket.getInputStream().read(b);
// System.out.println(new String(b, 0, len));
//
// System.in.read();
}
}
客户端
/**
* @author WuYongheng
* @date 2022/10/11
* @description
*/
import java.io.IOException;
import java.net.Socket;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class ClientThread extends Thread {
Socket socket;
public ClientThread() {
}
public ClientThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
byte[] b = new byte[300];
try {
while (true) {
int len = socket.getInputStream().read(b);
String s = new String(b, 0, len);
System.out.println("\t\t\t\t\t^_^" +"收到:"+ s);
}
} catch (Exception e) {
}
}
}
class Client {
/**
* 检查ip地址是否正确?使用正则表达式
* @param ip
* @return
*/
static boolean isIp(String ip) {
String str = ip;
String pattern = "((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(str);
boolean flag = m.matches();
return flag;
}
public static void main(String[] args) throws IOException {
if (args.length != 2) {
System.out.println("使用方法: java 程序 服务器IP 端口");
return;
}
if (!isIp(args[0])) {
System.out.println("无效的ip地址格式");
return;
}
int port = 0;
try {
port = Integer.parseInt(args[1]);
if (port < 5555 || port > 9999) {
System.err.println("无效的端口,端口必须在5555~9999之间");
return;
}
} catch (Exception e) {
System.err.println("无效的端口,端口必须在5555~9999之间");
return;
}
Socket socket = new Socket(args[0], port);//两个参数,ip地址,端口
//创建一个线程负责读服务器发来的消息,这样实现了客户端,服务器同时接收,发送信息
new ClientThread(socket).start();
String s = null;
byte[] b = new byte[300];
while (true) {//死循环,客户端一直发消息
System.out.print("chat>");
int len = System.in.read(b);
len = len - 1;//处理用户直接回车
if (len == 0) {
continue;
}
if (b[len - 1] == 13) {
len = len - 1;
}
if (len == 0) {
continue;
}
s = new String(b, 0, len);
if (s.contentEquals("exit") || s.contentEquals("quit")) {//处理用户想退出程序
System.out.println("欢迎再次使用");
return;
}
socket.getOutputStream().write(b, 0, len);
}
// socket.getOutputStream().write("hello".getBytes());
// System.in.read();
}
}
项目结构
注意添加jar包
点击小锤子 Build Project
之后会生成out目录(这里使用的是idea,如果使用eclipse的话,会生成bin目录)
进入out目录,将下载的jar包复制到这里,和 .class文件放在一起
使用方法
输入cmd打开4个命令行,启动1个服务器和3个客户端
效果
延申 在不同的主机上运行客户端 实现聊天
需要在同一个大网段下,比如两台电脑连接同一个wifi或者热点
步骤
将客户端的java文件发送到另一个主机上
使用命令生成字节码文件 javac Client.java
在本机开一个服务器和客户端
注意ip地址的变化
在另一个主机上开一个客户端,这台机器分配的ip地址和主机不一样,但在同一个大网段下
先试试能不能ping通
效果:
数据库