Java Thread与另一个完全不相关的线程一起关闭

时间:2015-02-27 19:35:56

标签: java multithreading

所以,我试图通过客户端 - 服务器通信为多个用户创建聊天。然而,如果一个客户端与服务器断开连接(由关键字 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;
    }
}

0 个答案:

没有答案