В последнее время я играю в возможности Java для работы в сети и многопоточности, просто в качестве фона я пытаюсь разработать многопоточное приложение для чата.
Проблема в том, что когда клиент отправляет сообщение, которое использует неправильный формат, например:
«UserID # Message» вместо «UserID * Message» выдается исключение, поток полностью останавливается, клиент должен закрыть свой сеанс и снова открыть его, чтобы восстановить соединение с сервером, а не возобновлять работу после ошибки и я не могу возобновить это.
Вот код сервера:
package AdvanceThreading.Server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
private ServerSocket serverSocket;
private Socket socket;
private DataInputStream messageFromClientToHandler;
private DataOutputStream messageFromHandlerToRecipient;
private int port;
private static int userID;
private ArrayList<ClientHandler> clientList;
public Server(int port) {
this.port = port;
this.userID = 0;
clientList = new ArrayList<>();
this.initialize();
}
public void initialize() {
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
messageFromClientToHandler = new DataInputStream(socket.getInputStream());
messageFromHandlerToRecipient = new DataOutputStream(socket.getOutputStream());
String userName = messageFromClientToHandler.readUTF();
messageFromHandlerToRecipient.writeInt(userID);
ClientHandler client = new ClientHandler(userID, userName, this, socket, messageFromClientToHandler, messageFromHandlerToRecipient);
clientList.add(client);
//Should set client.setUncaughtExceptionHandler();
client.start();
userID = userID + 1;
} catch (IOException e) {
e.printStackTrace();
}
}
}
public ServerSocket getServerSocket() {
return serverSocket;
}
public Socket getSocket() {
return socket;
}
public DataInputStream getMessageFromClientToHandler() {
return messageFromClientToHandler;
}
public DataOutputStream getMessageFromHandlerToRecipient() {
return messageFromHandlerToRecipient;
}
public int getPort() {
return port;
}
public static int getUserID() {
return userID;
}
public ArrayList<ClientHandler> getClientList() {
return clientList;
}
public static void main(String[] args) {
Server server = new Server(5050);
}
}
Код обработчика клиента:
package AdvanceThreading.Server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.StringTokenizer;
public class ClientHandler extends Thread {
private int clientID;
private String clientName;
private boolean loggedIn;
private Socket socket;
private Server server;
private DataInputStream messageFromClientToHandler;
private DataOutputStream messageFromHandlerToRecipient;
public ClientHandler(int clientID, String clientName, Server server, Socket socket, DataInputStream messageFromClientToHandler, DataOutputStream messageFromHandlerToRecipient) {
this.clientID = clientID;
this.clientName = clientName;
this.loggedIn = true;
this.server = server;
this.socket = socket;
this.messageFromClientToHandler = messageFromClientToHandler;
this.messageFromHandlerToRecipient = messageFromHandlerToRecipient;
}
@Override
public void run() {
String receivedFromClient;
StringTokenizer tokenize = null;
while (true) {
try {
receivedFromClient = messageFromClientToHandler.readUTF();
System.out.println(receivedFromClient);
tokenize = new StringTokenizer(receivedFromClient, "#");
String recipient = tokenize.nextToken();
int recipientID = Integer.parseInt(tokenize.nextToken());
String message = tokenize.nextToken();
//Need to handle exception of client not found.
for (ClientHandler client : server.getClientList()) {
if (client.getClientID() == recipientID && client.isLoggedIn()) {
client.getMessageFromHandlerToRecipient().writeUTF(this.clientName + ": " + message);
break;
}
}
} catch (IOException e) {
while (tokenize != null && tokenize.hasMoreTokens())
tokenize.nextToken();
e.printStackTrace();
}
}
}
public String getClientName() {
return clientName;
}
public void setClientName(String clientName) {
this.clientName = clientName;
}
public boolean isLoggedIn() {
return loggedIn;
}
public void setLoggedIn(boolean loggedIn) {
this.loggedIn = loggedIn;
}
public int getClientID() {
return clientID;
}
public Socket getSocket() {
return socket;
}
public Server getServer() {
return server;
}
public DataInputStream getMessageFromClientToHandler() {
return messageFromClientToHandler;
}
public DataOutputStream getMessageFromHandlerToRecipient() {
return messageFromHandlerToRecipient;
}
}
Главное, что я хочу сделать, если клиент, использующий терминал (например, CMD), делает ошибку, я хочу перехватить ошибку, обработать ее и возобновить сеанс на том же терминале, чтобы ему не пришлось Снова подключитесь к серверу.