线程分配错误



如果我运行服务器和只有一个客户端,它工作得很好。但是如果我再运行一个客户端,那么第一个客户端就会停止工作。处理第一个客户端请求的线程,突然,它处理第二个客户机的请求。所以第二个客户在聊天软件中输入一个单词,它会被打印两次。我只能在Eclipse上终止它。(甚至应用程序上的停止按钮都不起作用)服务器工作正常。没有例外之类的。控制台视图上没有错误日志。我都不会谷歌。因为没有消息或日志。请告诉我该怎么做。我应该在哪里修改代码

public void connectServer() {
try {

socket = new Socket(ip, 8888);
System.out.println("[Client]Server connected: "+ socket.getRemoteSocketAddress());
outMsg = new PrintWriter(socket.getOutputStream(), true);
outMsg.println(id+"/"+"login"); 
}catch (Exception e) {
if(!socket.isClosed()) { stopClient();}
return; 
}
receive();
} 
public void stopClient() {
msgOut.append("Disconnected");

try {
inMsg.close();
outMsg.close();
if(socket!=null && !socket.isClosed()) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}//stopClient
public void receive() {
while(true) {
try {
String msg;
String[] rmsg;
inMsg = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while(true) {              
msg = inMsg.readLine();
rmsg = msg.split("/");                 
msgOut.append(rmsg[0] + ">"+rmsg[1] + "n");          
msgOut.setCaretPosition(msgOut.getDocument().getLength());
}
} catch (Exception e) {
stopClient();
break; 
}

}//while
}//receive

public void send(String send) {
try {
outMsg = new PrintWriter(socket.getOutputStream(), true);
outMsg.println(id + "/" + send);

msgInput.setText("");
} catch (Exception e) {
msgOut.append("Disconnected");
stopClient();
} 

}

public void actionPerformed(ActionEvent arg0) {
Object obj = arg0.getSource();

if(obj == exitButton) {
System.exit(0);
} 
else if(obj == loginButton) {
id = idInput.getText();
label2.setText("name : " + id);
clayout.show(tab, "logout");
connectServer();
} 
else if(obj == logoutButton) {
outMsg.println(id + "/" + "logout");

msgOut.setText("");
clayout.show(tab, "login");
stopClient();

} 
else if(obj == msgInput) {
String chat = msgInput.getText();
send(chat);

}
}

public static void main(String[] args) {
MultiChatClient mcc = new MultiChatClient("127.0.0.1");

}

}

public class MultiChatServer {
ExecutorService executorService;
private ServerSocket ss;
private Socket s;
ArrayList <Client> clients_connected = new ArrayList <Client>();

void start() {
executorService = Executors.newFixedThreadPool
(Runtime.getRuntime().availableProcessors()); 

try {
ss = new ServerSocket(8888);
System.out.println("sever start");
}catch (Exception e) {
if(!ss.isClosed()) {
stopServer();
}
return;
}
Runnable runnable = new Runnable() {

@Override
public void run() {
while(true) {
try {
System.out.println("waiting");
s= ss.accept();
InetSocketAddress socketAddress = 
(InetSocketAddress) s.getRemoteSocketAddress();
System.out.println("Client("+socketAddress.getHostName()
+") connected ["+Thread.currentThread().getName()+"]");  
Client client = new Client(s);
clients_connected.add(client); 
System.out.println("connected number: " +clients_connected.size());

} catch (IOException e) {
if(!ss.isClosed()) {
stopServer();
}
break;
}

}
}   //run() 
};//runnable
executorService.submit(runnable);
}//start()

void stopServer() {
try {
Iterator<Client>iterator=clients_connected.iterator();
while(iterator.hasNext()) {
Client client = iterator.next();
client.socket.close(); 
iterator.remove();
}

if(ss!=null && !ss.isClosed())

ss.close(); 


if(executorService!=null && !executorService.isShutdown()) 

executorService.shutdown();

System.out.println("서버멈춤");
}catch (Exception e) {
// TODO: handle exception
}

}
class Client {
Socket socket; 
PrintWriter outMsg;
public Client() {}
public Client(Socket socket) { 
this.socket = socket;

receive();
}

void receive() {


Runnable runnable = new Runnable() {

@Override
public void run() {
try {
while(true) { 
BufferedReader inMsg = new BufferedReader
(new InputStreamReader(s.getInputStream()));
String msg = inMsg.readLine();
System.out.println("handling: " + s.getRemoteSocketAddress()
+": " + Thread.currentThread().getName());
String[] rmsg = msg.split("/");

if(rmsg[1].equals("logout")) {
sendAll("server/" + rmsg[0] + "is out.");
throw new IOException(); 

}

else if(rmsg[1].equals("login")) {
sendAll("server/"+rmsg[0]+"is entered.");
}

else {
sendAll(msg);
}

}
} catch (Exception e) {
try {
System.out.println("Disconnected: " +s.getRemoteSocketAddress()
+": " + Thread.currentThread().getName());
clients_connected.remove(Client.this);
s.close();
} catch (Exception e2) {}

}


}

};

executorService.submit(runnable); 
}

void sendAll(String Data) {

Runnable runnable = new Runnable() {

@Override
public void run() {

try {
outMsg = new PrintWriter(s.getOutputStream(),true);


for(Client client: clients_connected) {
client.outMsg.println(Data); //
}
} catch (IOException e) {
try {
System.out.println("Disconnected: " +s.getRemoteSocketAddress()
+": " + Thread.currentThread().getName());
clients_connected.remove(Client.this);
s.close();
}catch (Exception e2) {}
}

}
};

executorService.submit(runnable);


}
}


public static void main(String[] args) {
MultiChatServer server = new MultiChatServer();
server.start();
}

输入图片描述

服务器和客户端都在等待接收对方的消息,因为它们都处于等待阶段。

你可以用两种方法解决这个问题,

  1. 客户端等待接收,或者客户端等待接收,服务端等待发送。
  2. 在单独的线程上运行发送和接收

最新更新