最近完成了长连接的搭建,长连接相对于短链接有很多好处,其中最值得一提的就是他的数据是实时更新的、
先来简单介绍一下长连接:
所谓长连接,指在一个TCP连接上可以连续发送多个数据包,在TCP连接保持期间,如果没有数据包发送,需要双方发检测包以维持此连接,一般需要自己做在线维持。
短连接是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接,一般银行都使用短连接。
比如http的,只是连接、请求、关闭,过程时间较短,服务器若是一段时间内没有收到请求即可关闭连接。
其实长连接是相对于通常的短连接而说的,也就是长时间保持客户端与服务端的连接状态。、
什么时候用长连接,短连接?
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况,。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接, 如果用短连接频繁的通信会造成socket错误,而且频繁的socket 创建也是对资源的浪费。
而像WEB网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源,而像WEB网站这么频繁的成千上万甚至上亿客户端的连接用短连接会更省一些资源,如果用长连接,而且同时有成千上万的用户,如果每个用户都占用一个连接的话,那可想而知吧。所以并发量大,但每个用户无需频繁操作情况下需用短连好。
总之,长连接和短连接的选择要视情况而定。
长连接其实就是异步链接,就属于当初我们学习的生产者和消费者模型
异步就是报文发送和接收是分开的,相互独立的,互不影响。这种方式又分两种情况:
(1)异步双工:接收和发送在同一个程序中,由两个不同的子进程分别负责发送和接收
(2)异步单工:接收和发送是用两个不同的程序来完成。
2.图片的更改
图片的储存由于他是图片的类型则需要序列化与反序列化才能进行储存
public void image1() throws Exception {
String url = "jdbc:mysql://localhost:3306/users";
String user = "root";
String password = "1b0o2o6skobe";
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 注册 JDBC 驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 打开连接
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(url, user, password);
String sql = "UPDATE student SET imagePath=? WHERE account=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, this.image); // 假设 imagePath 是当前对象的属性
pstmt.setString(2, this.account); // 假设 account 是当前对象的属性
// 打印调试信息
System.out.println("Updating imagePath to " + this.image + " where account = " + this.account);
int rowsUpdated = pstmt.executeUpdate();
System.out.println(rowsUpdated + " row(s) updated.");
if (rowsUpdated == 0) {
System.out.println("No rows were updated. Please check if the account exists and the imagePath is different.");
}
} catch (SQLException se) {
// 处理 JDBC 错误
se.printStackTrace();
System.err.println("SQL Error: " + se.getMessage());
flag = 0;
} catch (ClassNotFoundException e) {
// 处理 Class.forName 错误
e.printStackTrace();
System.err.println("Driver not found: " + e.getMessage());
flag = 0;
} catch (Exception e) {
// 处理其他错误
e.printStackTrace();
System.err.println("An unexpected error occurred: " + e.getMessage());
flag = 0;
} finally {
// 关闭资源
try {
if (pstmt != null) pstmt.close();
} catch (SQLException se2) {
se2.printStackTrace();
}
try {
if (conn != null) conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
System.out.println("End of program.");
}
发送到服务器并识别图片的地址
public void image1() throws Exception {
String url = "jdbc:mysql://localhost:3306/users";
String user = "root";
String password = "1b0o2o6skobe";
Connection conn = null;
PreparedStatement pstmt = null;
try {
// 注册 JDBC 驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 打开连接
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(url, user, password);
String sql = "UPDATE student SET imagePath=? WHERE account=?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, this.image); // 假设 imagePath 是当前对象的属性
pstmt.setString(2, this.account); // 假设 account 是当前对象的属性
// 打印调试信息
System.out.println("Updating imagePath to " + this.image + " where account = " + this.account);
int rowsUpdated = pstmt.executeUpdate();
System.out.println(rowsUpdated + " row(s) updated.");
if (rowsUpdated == 0) {
System.out.println("No rows were updated. Please check if the account exists and the imagePath is different.");
}
} catch (SQLException se) {
// 处理 JDBC 错误
se.printStackTrace();
System.err.println("SQL Error: " + se.getMessage());
flag = 0;
} catch (ClassNotFoundException e) {
// 处理 Class.forName 错误
e.printStackTrace();
System.err.println("Driver not found: " + e.getMessage());
flag = 0;
} catch (Exception e) {
// 处理其他错误
e.printStackTrace();
System.err.println("An unexpected error occurred: " + e.getMessage());
flag = 0;
} finally {
// 关闭资源
try {
if (pstmt != null) pstmt.close();
} catch (SQLException se2) {
se2.printStackTrace();
}
try {
if (conn != null) conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
System.out.println("End of program.");
}
服务器接收并链接数据库进行更改后把图片的地址保存到数据库
if(operation.equals(markTool.image)){
Users2 users2 = (Users2) msg2;
//用户名非空
if(users2.account == null){
Mysqlconnection.flag= 0;
}
//添加user信息,如果重复,flag变为0
new Mysqlconnection(users2.image,users2.account).image1();
if(Mysqlconnection.flag == 0){
oos.writeObject(markTool.imagefail);
Mysqlconnection.flag = 1;
//oos.close();
}else{
oos.writeObject(markTool.imagesuccess);
System.out.println(users2.image);
System.out.println(users2.account);
//oos.close();
}
}
收取到客户端发来的信息进行更改并把消息传回客户端