所以,我试图通过客户端 - 服务器通信为多个用户创建聊天。然而,如果一个客户端与服务器断开连接(由关键字 exit 触发,因为该程序是基于控制台的atm,因为UI尚未完成),连接和聊天工作已经非常好了,其中一个其他 ClientIO -Threads会关闭与断开连接客户端相关的其他内容。我只是不知道为什么,因为那些线程只处理发送消息的客户端的输出。
我用3个客户测试了该程序。似乎如果你关闭客户端1或2(退出; ID为连接顺序,从0开始),客户端0的 ClientIO -Thread将关闭。如果关闭客户端0,则线程1将关闭。
为什么会这样?我如何解决它?
如果我提出问题的方式有问题,请第一次问自己时,请放轻松。提前谢谢!
服务器:
类服务器:
import java.io.*;
import java.net.*;
public class Server extends Thread{
int n = 0;
private Socket angekommenerClient;
private ServerSocket sSocket;
Liste client_Liste;
public Server (int port) {
try {
//System.out.println("konst1");
sSocket = new ServerSocket (port);
//System.out.println("konst2");
client_Liste=new Liste();
}catch (Exception e){e.printStackTrace();}
}
public void run(){
try {
//System.out.println("try");
InputStreamReader isr;
BufferedReader br;
while (true) {
//System.out.println("while");
/**Verbindungsannahme**/
angekommenerClient = sSocket.accept();
System.out.println("accept");
InputStream input=angekommenerClient.getInputStream();
OutputStream output=angekommenerClient.getOutputStream();
/**Übergabe Username**/
isr = new InputStreamReader(input);
br = new BufferedReader(isr);
String username = br.readLine();
/**Datenerfassung**/
client_PC neu = new client_PC(angekommenerClient,output,angekommenerClient.getInetAddress(), n, username);
client_Liste.insert(neu);
n++;
client_Liste.toFirst();
System.out.println("test "+((client_PC)client_Liste.getObject()).getID());
/**Vebindungsaufbau**/
new Connection (neu, new BufferedReader(new InputStreamReader(input)));
}
}catch (Exception e){e.printStackTrace();}
}
class Connection{
private BufferedReader client_input; // vom Client
private client_PC client;
private String client_anwender;
private ClientIO cIO;
public Connection(client_PC c, BufferedReader ci){
client=c;
client_input=ci;
cIO=new ClientIO();
cIO.start();
}
class ClientIO extends Thread{
boolean closed = false;
public void run(){
PrintStream ps = null;
while(!client.getSocket().isClosed() && !closed){
try{
if(client_input.ready()){
if(!client_Liste.isEmpty()){
/**Nachricht einlesen**/
System.out.println("listen");
String msg = client_input.readLine();
System.out.println("Input: "+msg);
/**Abmeldung erfahren**/
if(msg.equals("exit")){
closed = true;
}
/**Nachricht weiterleiten...**/
client_Liste.toFirst();
while(client_Liste.hasAccess()){
client_PC cpc = ((client_PC)client_Liste.getObject());
System.out.println("ID: "+cpc.getID());
/**...außer an sich selbst**/
if(cpc.getID()!=client.getID()){
ps = new PrintStream(cpc.getOutput());
ps.println(client.getUsername() + "(" + client.getID() + "): " + msg);
}
client_Liste.next();
}
System.out.println("finish");
}
}
}catch(Exception e){e.printStackTrace();};
}
/**Offenes schließen**/
if(ps != null){
ps.close();
}
System.out.println("disconnected" + client.getID());
stop();
}
}
}
}
class client_PC:
import java.io.*;
import java.net.*;
public class client_PC{
private Socket client_Socket;
private OutputStream client_Output;
private InetAddress client_IP;
private Object client_Info=null;
private int ID;
private String username;
public client_PC(Socket c_Socket,OutputStream c_Output,InetAddress c_IP, int id, String uname){
client_Socket=c_Socket;
client_Output=c_Output;
client_IP=c_IP;
ID = id;
username = uname;
}
public InetAddress getInetAddress(){
return client_IP;
}
public Socket getSocket(){
return client_Socket;
}
public int getID(){
return ID;
}
public OutputStream getOutput(){
return client_Output;
}
public void setInfo(Object info){
client_Info=info;
}
public Object getInfo(){
return client_Info;
}
public String getUsername(){
return username;
}
}
课堂听力:
public class Liste{
private ListElement ListKopf;
private ListElement VorAktuellerZeiger, AktuellerZeiger;
Liste(){
ListKopf=null;
AktuellerZeiger=null;
VorAktuellerZeiger=null;
}
boolean isEmpty(){
return (ListKopf==null);
}
public boolean hasAccess() {
return (!this.isEmpty() && AktuellerZeiger!=null);
}
public void next(){
if (this.hasAccess()){
ListElement Hilf=AktuellerZeiger;
AktuellerZeiger=AktuellerZeiger.naechstes;
VorAktuellerZeiger=Hilf;
}
}
public void toFirst() {
AktuellerZeiger=ListKopf;
VorAktuellerZeiger=null;
}
public void toLast() {
if(!hasAccess())this.toFirst();
if(AktuellerZeiger!=null){
while(AktuellerZeiger.naechstes!=null)
next();
}
}
public Object getObject(){
if (this.hasAccess())
return AktuellerZeiger.Inhalt;
else
return null;
}
public void setObject(Object pObject){
if (pObject!=null && this.hasAccess()){
remove();
insvor(pObject);
}
}
private void insvor(Object x){
ListElement Neu= new ListElement(x,AktuellerZeiger);
if(VorAktuellerZeiger==null){ListKopf=Neu; AktuellerZeiger=Neu;}
else {VorAktuellerZeiger.naechstes=Neu;}
}
private void insnach(Object x){
next();
insvor(x);
}
public void insert(Object pObject){
if (pObject!=null)
insvor(pObject);
}
public void append(Object pObject){
if (pObject!=null){
this.toLast();
if(this.hasAccess())
insnach(pObject);
}
}
public void remove(){
if(AktuellerZeiger!=null){
AktuellerZeiger=AktuellerZeiger.naechstes;
if(VorAktuellerZeiger==null){ListKopf=AktuellerZeiger;}
else {VorAktuellerZeiger.naechstes=AktuellerZeiger;}
}
}
}
class ListElement:
public class ListElement{
protected Object Inhalt;
protected ListElement naechstes;
ListElement (Object x, ListElement n){
Inhalt = x;
naechstes = n;
}
}
客户:
班级客户:
import java.io.*;
import java.net.*;
public class Client
{
//String IP = "10.16.139.3";
String IP = "localhost";
String name;
int port = 5000;
Socket socket;
ClientThread t1, t2;
public Client(String n){
name = n;
}
public void main() throws IOException{
/**Socket**/
socket = new Socket(IP, port);
/**Übergabe Name**/
PrintStream ps = new PrintStream(socket.getOutputStream());
ps.println(name);
/**Verbindungs-Threads**/
t1 = new ClientThread(System.in, socket.getOutputStream(), true);
t2 = new ClientThread(socket.getInputStream(), System.out, false);
t1.start();
t2.start();
while(t1.isAlive() && t2.isAlive()){}
ps.close();
socket.close();
}
}
class ClientThread:
import java.awt.*;
import java.lang.*;
import java.io.*;
import java.net.*;
public class ClientThread extends Thread{
boolean halt = false, isSender;
InputStream is;
InputStreamReader isr;
BufferedReader br;
String msg;
OutputStream os;
PrintStream ps;
public ClientThread(InputStream s1, OutputStream s2, boolean s)
{
try{
isSender = s;
is = s1;
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
os = s2;
ps = new PrintStream(os);
}catch(Exception e){e.printStackTrace();}
}
public void run(){
while (!halt){
try{
if(br.ready()){
msg = br.readLine();
if(msg != null){
ps.println(msg);
if((msg.equals("exit") || msg.trim().equals("null"))&&isSender){stopp(); stop();}
}
else{
System.out.println("Error msg: "+msg);
}
}
}catch(Exception e){e.printStackTrace();}
}
}
public void stopp(){
halt = true;
}
public void weiter(){
halt = false;
}
}