Anonymous
Нулевая ошибка во время выполнения обработчика клиента в Java MultiThread
Сообщение
Anonymous » 06 фев 2025, 13:37
При тестировании этого кода я получил на одной стороне (клиент): ошибка во время выполнения: потоковой закрыт; в то время как на стороне сервера Следующая ошибка: ошибка при выполнении обработчика клиента: null; Код сервера следующим образом: < /p>
Код: Выделить всё
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;
import java.util.concurrent.CopyOnWriteArrayList;
public class ServerSocketChat {
private static final CopyOnWriteArrayList currentThreads = new CopyOnWriteArrayList();
private static final int PORT = 12345;
private static final int MAX_USERS = 10;
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("Server sta ascoltando sulla porta " + PORT);
while (true) {
try {
Socket clientSocket = serverSocket.accept();
// Check max users before creating handler
if (currentThreads.size() >= MAX_USERS) {
System.out.println("Numero massimo di utenti raggiunto. Connessione rifiutata.");
clientSocket.close();
continue;
}
System.out.println("Nuova connessione accettata " + clientSocket.getInetAddress());
// Create and start client handler
ClientHandler clientHandler = new ClientHandler(clientSocket);
Thread clientThread = new Thread(clientHandler);
currentThreads.add(clientThread);
clientThread.start();
// Clean up terminated threads
currentThreads.removeIf(thread -> !thread.isAlive());
} catch (IOException e) {
System.err.println("Errore nella gestione della connessione: " + e.getMessage());
}
}
} catch (IOException e) {
System.err.println("Errore critico nel server: " + e.getMessage());
}
}
}
< /code>
Между тем код обработчика клиента следующим: < /p>
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
public class ClientHandler extends Thread {
private final Socket socket;
private Connection connection;
public ClientHandler(Socket socket) {
this.socket = socket;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/DB_WhatApp_2_Fantini", "root", "");
} catch (ClassNotFoundException | SQLException e) {
System.err.println("Errore connessione db: " + e.getMessage());
return;
}
}
@Override
public void run() {
try (ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream())) {
String request;
while ((request = (String) in.readObject()) != null) {
if ("close".equals(request)) {
System.out.println("Client ha chiuso la connessione.");
break; // Esci dal ciclo se il client ha chiuso la connessione
}
String[] parts = request.split(",");
String action = parts[0];
switch (action) {
case "login" -> out.writeObject(login(parts[1], parts[2]));
case "TrovaChat" -> {
LinkedList emails = new LinkedList();
out.writeObject(getChat(parts[1], emails));
}
case "NuovaChat" -> out.writeObject(newChat(parts[1], parts[2]));
case "TrovaMessaggi" -> out.writeObject(getMessaggi(parts[1], parts[2]));
case "NuovoMessaggio" -> out.writeObject(newMessaggio(parts[1], parts[2], parts[3]));
default -> out.writeObject("Comando non valido");
}
}
} catch (ClassNotFoundException | IOException e) {
System.err.println("Errore durante l'esecuzione del client handler: " + e.getMessage());
} finally {
try {
if (connection != null) connection.close();
if (socket != null) socket.close();
} catch (SQLException | IOException e) {
System.err.println("Errore durante la chiusura delle risorse: " + e.getMessage());
}
}
}
private String login(String email, String password) {
String query = "SELECT COUNT(*) FROM UTENTE WHERE email = ? AND password = ?";
try (PreparedStatement stmt = connection.prepareStatement(query)) {
stmt.setString(1, email);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
rs.next();
return rs.getInt(1) > 0 ? "AUTH_SUCCESS" : "AUTH_FAIL";
} catch (SQLException e) {
return "DB_ERROR: " + e.getMessage();
}
}
private String getMessaggi(String senderEmail, String recipientEmail) {
StringBuilder messages = new StringBuilder();
String updateQuery = "UPDATE MESSAGGIO SET flag_letto = TRUE WHERE " +
"ID_UTENTE_MITTENTE = (SELECT ID FROM UTENTE WHERE email = ?) AND " +
"ID_UTENTE_DESTINATARIO = (SELECT ID FROM UTENTE WHERE email = ?);";
try {
connection.setAutoCommit(false);
try (PreparedStatement updateStmt = connection.prepareStatement(updateQuery)) {
updateStmt.setString(1, recipientEmail);
updateStmt.setString(2, senderEmail);
updateStmt.executeUpdate();
}
String selectQuery = "SELECT data_ora, testo, CONCAT(s.COGNOME,' ',s.NOME) as sender " +
"FROM MESSAGGIO m LEFT JOIN UTENTE s ON m.ID_UTENTE_MITTENTE = s.ID " +
"LEFT JOIN UTENTE r ON m.ID_UTENTE_DESTINATARIO = r.ID " +
"WHERE (r.email = ? OR r.email = ?) AND (s.email = ? OR s.email = ?) " +
"ORDER BY data_ora ASC;";
try (PreparedStatement selectStmt = connection.prepareStatement(selectQuery)) {
selectStmt.setString(1, senderEmail);
selectStmt.setString(2, recipientEmail);
selectStmt.setString(3, senderEmail);
selectStmt.setString(4, recipientEmail);
ResultSet rs = selectStmt.executeQuery();
while (rs.next()) {
messages.append(rs.getTimestamp("data_ora"))
.append(" - ").append(rs.getString("sender")).append(": ")
.append(rs.getString("testo")).append("\n");
}
}
connection.commit();
return messages.toString();
} catch (SQLException e) {
try {
connection.rollback();
} catch (SQLException ex) {
System.err.println("Errore durante il rollback: " + ex.getMessage());
}
return "DB_ERROR: " + e.getMessage();
}
}
private String getChat(String email, LinkedList emails) {
StringBuilder chats = new StringBuilder();
String query = "SELECT DISTINCT u.nome, u.cognome, u.email FROM UTENTE u " +
"JOIN (SELECT m.ID, m.ID_UTENTE_MITTENTE, m.ID_UTENTE_DESTINATARIO FROM MESSAGGIO m " +
"WHERE m.ID_UTENTE_MITTENTE = (SELECT ID FROM UTENTE WHERE email = ?) " +
"OR m.ID_UTENTE_DESTINATARIO = (SELECT ID FROM UTENTE WHERE email = ?)) AS sub " +
"ON u.ID = sub.ID_UTENTE_MITTENTE OR u.ID = sub.ID_UTENTE_DESTINATARIO WHERE u.email != ?;";
try (PreparedStatement stmt = connection.prepareStatement(query)) {
stmt.setString(1, email);
stmt.setString(2, email);
stmt.setString(3, email);
ResultSet rs = stmt.executeQuery();
int index = 1;
while (rs.next()) {
chats.append(index++).append(" - Apri chat con ").append(rs.getString("cognome")).append(" ").append(rs.getString("nome")).append(" ").append(rs.getString("email")).append("\n");
emails.add(rs.getString("email"));
}
return chats.toString();
} catch (SQLException e) {
return "DB_ERROR: " + e.getMessage();
}
}
private String newChat(String senderEmail, String recipientEmail) {
try {
connection.setAutoCommit(false);
int recipientId = getUserId(recipientEmail);
if (recipientId == -1) return "Utente non trovato";
int senderId = getUserId(senderEmail);
if (senderId == -1) return "Utente non trovato";
if (chatExists(senderEmail, recipientEmail)) return "Chat gia' esistente";
String createChat = "INSERT INTO MESSAGGIO (ID_UTENTE_MITTENTE, ID_UTENTE_DESTINATARIO, DATA_ORA, TESTO) VALUES (?, ?, NOW(), '');";
try (PreparedStatement stmt = connection.prepareStatement(createChat)) {
stmt.setInt(1, senderId);
stmt.setInt(2, recipientId);
stmt.executeUpdate();
}
connection.commit();
return "Chat creata";
} catch (SQLException e) {
try {
connection.rollback();
} catch (SQLException ex) {
System.err.println("Errore durante il rollback: " + ex.getMessage());
}
return "DB_ERROR: " + e.getMessage();
}
}
private int getUserId(String email) throws SQLException {
String query = "SELECT ID FROM UTENTE WHERE email = ?";
try (PreparedStatement stmt = connection.prepareStatement(query)) {
stmt.setString(1, email);
ResultSet rs = stmt.executeQuery();
return rs.next() ? rs.getInt("ID") : -1;
}
}
private boolean chatExists(String senderEmail, String recipientEmail) throws SQLException {
String query = "SELECT m.ID FROM MESSAGGIO m " +
"JOIN UTENTE s ON m.ID_UTENTE_MITTENTE = s.ID " +
"JOIN UTENTE r ON m.ID_UTENTE_DESTINATARIO = r.ID " +
"WHERE (s.email = ? AND r.email = ?) OR (s.email = ? AND r.email = ?);";
try (PreparedStatement stmt = connection.prepareStatement(query)) {
stmt.setString(1, senderEmail);
stmt.setString(2, recipientEmail);
stmt.setString(3, recipientEmail);
stmt.setString(4, senderEmail);
ResultSet rs = stmt.executeQuery();
return rs.next();
}
}
private String newMessaggio(String senderEmail, String recipientEmail, String message) {
try {
connection.setAutoCommit(false);
int recipientId = getUserId(recipientEmail);
if (recipientId == -1) return "USER_NOT_FOUND";
int senderId = getUserId(senderEmail);
if (senderId == -1) return "USER_NOT_FOUND";
String insertMessage = "INSERT INTO MESSAGGIO (ID_UTENTE_MITTENTE, ID_UTENTE_DESTINATARIO, data_ora, testo, flag_letto) VALUES (?, ?, NOW(), ?, FALSE)";
try (PreparedStatement stmt = connection.prepareStatement(insertMessage)) {
stmt.setInt(1, senderId);
stmt.setInt(2, recipientId);
stmt.setString(3, message);
stmt.executeUpdate();
}
connection.commit();
return "MESSAGE_INSERTED";
} catch (SQLException e) {
try {
connection.rollback();
} catch (SQLException ex) {
System.err.println("Errore durante il rollback: " + ex.getMessage());
}
return "DB_ERROR: " + e.getMessage();
}
}
}
Пожалуйста, я работал над этими кодами в течение 3 недель.
Подробнее здесь:
https://stackoverflow.com/questions/794 ... ultithread
1738838261
Anonymous
При тестировании этого кода я получил на одной стороне (клиент): ошибка во время выполнения: потоковой закрыт; в то время как на стороне сервера Следующая ошибка: ошибка при выполнении обработчика клиента: null; Код сервера следующим образом: < /p> [code]import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.LinkedList; import java.util.concurrent.CopyOnWriteArrayList; public class ServerSocketChat { private static final CopyOnWriteArrayList currentThreads = new CopyOnWriteArrayList(); private static final int PORT = 12345; private static final int MAX_USERS = 10; public static void main(String[] args) { try (ServerSocket serverSocket = new ServerSocket(PORT)) { System.out.println("Server sta ascoltando sulla porta " + PORT); while (true) { try { Socket clientSocket = serverSocket.accept(); // Check max users before creating handler if (currentThreads.size() >= MAX_USERS) { System.out.println("Numero massimo di utenti raggiunto. Connessione rifiutata."); clientSocket.close(); continue; } System.out.println("Nuova connessione accettata " + clientSocket.getInetAddress()); // Create and start client handler ClientHandler clientHandler = new ClientHandler(clientSocket); Thread clientThread = new Thread(clientHandler); currentThreads.add(clientThread); clientThread.start(); // Clean up terminated threads currentThreads.removeIf(thread -> !thread.isAlive()); } catch (IOException e) { System.err.println("Errore nella gestione della connessione: " + e.getMessage()); } } } catch (IOException e) { System.err.println("Errore critico nel server: " + e.getMessage()); } } } < /code> Между тем код обработчика клиента следующим: < /p> import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.LinkedList; public class ClientHandler extends Thread { private final Socket socket; private Connection connection; public ClientHandler(Socket socket) { this.socket = socket; try { Class.forName("com.mysql.cj.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/DB_WhatApp_2_Fantini", "root", ""); } catch (ClassNotFoundException | SQLException e) { System.err.println("Errore connessione db: " + e.getMessage()); return; } } @Override public void run() { try (ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream in = new ObjectInputStream(socket.getInputStream())) { String request; while ((request = (String) in.readObject()) != null) { if ("close".equals(request)) { System.out.println("Client ha chiuso la connessione."); break; // Esci dal ciclo se il client ha chiuso la connessione } String[] parts = request.split(","); String action = parts[0]; switch (action) { case "login" -> out.writeObject(login(parts[1], parts[2])); case "TrovaChat" -> { LinkedList emails = new LinkedList(); out.writeObject(getChat(parts[1], emails)); } case "NuovaChat" -> out.writeObject(newChat(parts[1], parts[2])); case "TrovaMessaggi" -> out.writeObject(getMessaggi(parts[1], parts[2])); case "NuovoMessaggio" -> out.writeObject(newMessaggio(parts[1], parts[2], parts[3])); default -> out.writeObject("Comando non valido"); } } } catch (ClassNotFoundException | IOException e) { System.err.println("Errore durante l'esecuzione del client handler: " + e.getMessage()); } finally { try { if (connection != null) connection.close(); if (socket != null) socket.close(); } catch (SQLException | IOException e) { System.err.println("Errore durante la chiusura delle risorse: " + e.getMessage()); } } } private String login(String email, String password) { String query = "SELECT COUNT(*) FROM UTENTE WHERE email = ? AND password = ?"; try (PreparedStatement stmt = connection.prepareStatement(query)) { stmt.setString(1, email); stmt.setString(2, password); ResultSet rs = stmt.executeQuery(); rs.next(); return rs.getInt(1) > 0 ? "AUTH_SUCCESS" : "AUTH_FAIL"; } catch (SQLException e) { return "DB_ERROR: " + e.getMessage(); } } private String getMessaggi(String senderEmail, String recipientEmail) { StringBuilder messages = new StringBuilder(); String updateQuery = "UPDATE MESSAGGIO SET flag_letto = TRUE WHERE " + "ID_UTENTE_MITTENTE = (SELECT ID FROM UTENTE WHERE email = ?) AND " + "ID_UTENTE_DESTINATARIO = (SELECT ID FROM UTENTE WHERE email = ?);"; try { connection.setAutoCommit(false); try (PreparedStatement updateStmt = connection.prepareStatement(updateQuery)) { updateStmt.setString(1, recipientEmail); updateStmt.setString(2, senderEmail); updateStmt.executeUpdate(); } String selectQuery = "SELECT data_ora, testo, CONCAT(s.COGNOME,' ',s.NOME) as sender " + "FROM MESSAGGIO m LEFT JOIN UTENTE s ON m.ID_UTENTE_MITTENTE = s.ID " + "LEFT JOIN UTENTE r ON m.ID_UTENTE_DESTINATARIO = r.ID " + "WHERE (r.email = ? OR r.email = ?) AND (s.email = ? OR s.email = ?) " + "ORDER BY data_ora ASC;"; try (PreparedStatement selectStmt = connection.prepareStatement(selectQuery)) { selectStmt.setString(1, senderEmail); selectStmt.setString(2, recipientEmail); selectStmt.setString(3, senderEmail); selectStmt.setString(4, recipientEmail); ResultSet rs = selectStmt.executeQuery(); while (rs.next()) { messages.append(rs.getTimestamp("data_ora")) .append(" - ").append(rs.getString("sender")).append(": ") .append(rs.getString("testo")).append("\n"); } } connection.commit(); return messages.toString(); } catch (SQLException e) { try { connection.rollback(); } catch (SQLException ex) { System.err.println("Errore durante il rollback: " + ex.getMessage()); } return "DB_ERROR: " + e.getMessage(); } } private String getChat(String email, LinkedList emails) { StringBuilder chats = new StringBuilder(); String query = "SELECT DISTINCT u.nome, u.cognome, u.email FROM UTENTE u " + "JOIN (SELECT m.ID, m.ID_UTENTE_MITTENTE, m.ID_UTENTE_DESTINATARIO FROM MESSAGGIO m " + "WHERE m.ID_UTENTE_MITTENTE = (SELECT ID FROM UTENTE WHERE email = ?) " + "OR m.ID_UTENTE_DESTINATARIO = (SELECT ID FROM UTENTE WHERE email = ?)) AS sub " + "ON u.ID = sub.ID_UTENTE_MITTENTE OR u.ID = sub.ID_UTENTE_DESTINATARIO WHERE u.email != ?;"; try (PreparedStatement stmt = connection.prepareStatement(query)) { stmt.setString(1, email); stmt.setString(2, email); stmt.setString(3, email); ResultSet rs = stmt.executeQuery(); int index = 1; while (rs.next()) { chats.append(index++).append(" - Apri chat con ").append(rs.getString("cognome")).append(" ").append(rs.getString("nome")).append(" ").append(rs.getString("email")).append("\n"); emails.add(rs.getString("email")); } return chats.toString(); } catch (SQLException e) { return "DB_ERROR: " + e.getMessage(); } } private String newChat(String senderEmail, String recipientEmail) { try { connection.setAutoCommit(false); int recipientId = getUserId(recipientEmail); if (recipientId == -1) return "Utente non trovato"; int senderId = getUserId(senderEmail); if (senderId == -1) return "Utente non trovato"; if (chatExists(senderEmail, recipientEmail)) return "Chat gia' esistente"; String createChat = "INSERT INTO MESSAGGIO (ID_UTENTE_MITTENTE, ID_UTENTE_DESTINATARIO, DATA_ORA, TESTO) VALUES (?, ?, NOW(), '');"; try (PreparedStatement stmt = connection.prepareStatement(createChat)) { stmt.setInt(1, senderId); stmt.setInt(2, recipientId); stmt.executeUpdate(); } connection.commit(); return "Chat creata"; } catch (SQLException e) { try { connection.rollback(); } catch (SQLException ex) { System.err.println("Errore durante il rollback: " + ex.getMessage()); } return "DB_ERROR: " + e.getMessage(); } } private int getUserId(String email) throws SQLException { String query = "SELECT ID FROM UTENTE WHERE email = ?"; try (PreparedStatement stmt = connection.prepareStatement(query)) { stmt.setString(1, email); ResultSet rs = stmt.executeQuery(); return rs.next() ? rs.getInt("ID") : -1; } } private boolean chatExists(String senderEmail, String recipientEmail) throws SQLException { String query = "SELECT m.ID FROM MESSAGGIO m " + "JOIN UTENTE s ON m.ID_UTENTE_MITTENTE = s.ID " + "JOIN UTENTE r ON m.ID_UTENTE_DESTINATARIO = r.ID " + "WHERE (s.email = ? AND r.email = ?) OR (s.email = ? AND r.email = ?);"; try (PreparedStatement stmt = connection.prepareStatement(query)) { stmt.setString(1, senderEmail); stmt.setString(2, recipientEmail); stmt.setString(3, recipientEmail); stmt.setString(4, senderEmail); ResultSet rs = stmt.executeQuery(); return rs.next(); } } private String newMessaggio(String senderEmail, String recipientEmail, String message) { try { connection.setAutoCommit(false); int recipientId = getUserId(recipientEmail); if (recipientId == -1) return "USER_NOT_FOUND"; int senderId = getUserId(senderEmail); if (senderId == -1) return "USER_NOT_FOUND"; String insertMessage = "INSERT INTO MESSAGGIO (ID_UTENTE_MITTENTE, ID_UTENTE_DESTINATARIO, data_ora, testo, flag_letto) VALUES (?, ?, NOW(), ?, FALSE)"; try (PreparedStatement stmt = connection.prepareStatement(insertMessage)) { stmt.setInt(1, senderId); stmt.setInt(2, recipientId); stmt.setString(3, message); stmt.executeUpdate(); } connection.commit(); return "MESSAGE_INSERTED"; } catch (SQLException e) { try { connection.rollback(); } catch (SQLException ex) { System.err.println("Errore durante il rollback: " + ex.getMessage()); } return "DB_ERROR: " + e.getMessage(); } } } [/code] Пожалуйста, я работал над этими кодами в течение 3 недель. Подробнее здесь: [url]https://stackoverflow.com/questions/79417560/null-error-during-client-handler-execution-in-java-multithread[/url]