我试图为我的一个班级制作聊天程序,但我遇到的问题是,例如,如果有3个客户端:A,B和C.他们都可以与每个人交谈其他罚款,但客户B断开连接,然后A和C不能再相互通话。我将我的客户端存储到一个向量中,我不确定如何在断开连接时删除它们。但是,我不相信这个问题。如果有人可以指出我正确的方向,那么这两个问题都会很棒!
服务器:
public class Server {
//vector to hold clients
static Vector<RequestHandler> connected = new Vector<>();
//client counter
static int numClients = 0;
//string to hold the server IP
protected static String serverIP;
public static void main(String[] args) throws IOException
{
//checks to see if port number was entered for server
if(args.length < 1)
{
System.err.println("Usage: java Server <port number>");
System.exit(1);
}
System.out.println("Server started. Listening on Port 8005");
//sets the port number to args passed in
int portNumber = Integer.parseInt(args[0]);
//declares executor to be used for thread gen
ExecutorService executor = null;
//tries to create new socket
try(ServerSocket serverSocket = new ServerSocket(portNumber);)
{
//creates thread pool w/ a thread for each client(# can vary)
executor = Executors.newFixedThreadPool(10);
System.out.println("Waiting for clients to connect...");
while(true)
{
//established socket connection
Socket clientSocket = serverSocket.accept();
RequestHandler worker = new RequestHandler(clientSocket);
//adds client requesthandler to active client list
connected.add(worker);
//increments client counter
numClients++;
//starts new thread
executor.execute(worker);
System.out.println("Client " + numClients + " connected");
}
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ portNumber + " or listening for a connection");
System.out.println(e.getMessage());
} finally {
if (executor != null) {
executor.shutdown();
}
}
}
public static void notifyClients(RequestHandler sender, String clientMSG) throws IOException
{
System.out.println("Echoing Message to " + (numClients-1) + " clients...");
for(RequestHandler tmp : connected)
{
if(!(tmp.equals(sender))) {
tmp.sendMSG("client " + sender + ": " + clientMSG);
System.out.println(sender + " wrote: \"" + clientMSG +
"\" to " + tmp);
}
}
}
}
请求处理程序:
public class RequestHandler implements Runnable {
private final Socket client;
ServerSocket serverSocket = null;
public RequestHandler(Socket client) {
this.client = client;
}
@Override
public void run()
{
try(BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));)
{
System.out.println("Thread started with name: " + Thread.currentThread().getName());
String clientMsg;
System.out.println("CLIENT: " + client);
while((clientMsg = input.readLine())!= null)
{
//removes special characters
clientMsg = clientMsg.replaceAll("[^A-Za-z0-9.?,:' ]", "");
//prints message to server terminal
//System.out.println("Received Message from " + Thread.currentThread().getName() + ": "+ clientMsg);
System.out.println("Received Message from " + client.getPort()+ ": " + clientMsg);
//sends message back to client that sent it
Server.notifyClients(this, clientMsg);
output.write("You entered: "+ clientMsg);
output.newLine(); //new lines
output.flush(); //clears output stream
}
} catch(IOException e) {
System.out.println("Client " + Server.numClients + " disconnected.");
Server.numClients--;
System.out.println("IO Excpetion: " + e);
} catch(Exception ex) {
System.out.println("Exception in thread run. Exeption: " + ex);
}
}
public void sendMSG(String msg) throws IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
writer.write(msg);
writer.newLine();
writer.flush();
}
}
答案 0 :(得分:0)
当您尝试向断开连接的客户端发送邮件时引发的IOException
notifyClients
正在查杀运行循环。
你应该抓住它并删除有问题的客户端:
// Synchronized set because we're in a multithreaded environment
static Set<RequestHandler> connected = Collections.synchronizedSet(new LinkedHashSet<>());
public static void notifyClients(RequestHandler sender, String clientMSG) {
System.out.println("Echoing Message to " + (numClients - 1) + " clients...");
// Defensive copy in case the client vector is modified while we iterate over it
List<RequestHandler> connected;
synchronized (Server.connected) {
connected = new ArrayList<>(Server.connected);
}
for (RequestHandler client : connected) {
try {
if (!(client.equals(sender))) {
client.sendMSG("client " + sender + ": " + clientMSG);
System.out.println(sender + " wrote: \"" + clientMSG + "\" to " + client);
}
} catch (IOException e) {
System.err.println("Couldn't write to " + client);
Server.connected.remove(client);
}
}
}