线程启动后,服务器/客户端程序停止工作

时间:2012-10-13 12:02:23

标签: java multithreading sockets user-interface

我在过去的5天里试图找出为什么我的程序不起作用我一直在这里问无数问题并且反应良好,而且我现在已经发现了问题。

背景故事:

我有一个聊天程序,分为两个单独的应用程序客户端和服务器。我们的想法是创建一个聊天程序,因此客户端拥有一个包含图片和一些标签以及一些textAreas的GUI。

每当客户端启动Gui show并且用户能够点击按钮连接以尝试连接服务器时,这直接发生在我的程序中,这部分程序运行良好:

**按下连接按钮** 客户端发送到服务器:1 服务器发送给客户端:1 服务器发送给客户端:1 客户端发送到服务器:Marc(聊天人用户名)

客户端发送到服务器:5 服务器发送给客户端:1 服务器发送给客户端:1 服务器发送给客户端:Marc

客户端发送到服务器:8 服务器发送给客户端:8

现在所有的地狱都崩溃了,因为现在我的Gui中的线程开始了。从这里开始,该程序显然无法从此处收到来自服务器的消息。即使服务器收到消息。怎么会这样?

为了不发布代码加载我将发布我的程序的重要部分如果你需要更多代码我很乐意更新帖子

线程(在simpleController中(控制GUI的那个))

public void run(){ 
    System.out.println("Thread started");
    System.out.println(client.getSocket().isConnected());
    ClientListner cl = new ClientListner(client);
    while (client.getSocket().isConnected()) {
        int key = 10;

            if (client.getInput().hasNext()) {
                txt_ChatPerson2.setText(client.reciveString());
                txt_ChatPerson2.setVisible(true);
            }
            try {
                key = client.reciveCommando();
                System.out.println("jeg er her");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }



        System.out.println("Key "+key);
        switch (key) {
        // case 2 er recive chat:
        case 2:
            // først find ud af hvilket ID der har sendt chatten:
            int y = 0;
            try {
                y = client.reciveCommando();
                System.out.println("y" + y); 
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // derefter få beskeden og send den så ud til resten.
            String says = client.reciveChat().toString();
            System.out.println("Says :"+says);
            if (y == 1) {
                txt_ChatPerson1.setText(says);
                txt_ChatPerson1.setVisible(true);
            }else if (y == 2) {
                txt_ChatPerson2.setText(says);
                txt_ChatPerson2.setVisible(true);
            }else {
                chatPerson3.setVisible(true);
                txt_ChatPerson3.setVisible(true);
                txt_ChatPerson3.setText(says);
            }

            break;

        default:
            break;
        }
    }
}

客户端类

 import java.io.IOException;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;


public class Client {
// disse var static
    public final static int portNumber = 6040;
    public Socket socket;
    private PrintWriter pw;
    private Scanner input;
    private int clientId;
    /**
     * @param args
     * @throws IOException 
     */

    public Client(Socket socket, PrintWriter pw, Scanner input, int clientId){
        this.socket = socket;
        this.pw = pw;
        this.input = input;
        this.clientId = clientId;
    }
    public void connect() throws IOException{
        // du kan vælge at bruge inetadressen til at connecte i socketet.
        InetAddress adr = InetAddress.getByName("localhost");
        socket = new Socket("localhost", portNumber);
        input=new Scanner(socket.getInputStream());
        pw = new PrintWriter(socket.getOutputStream());

    }
    /**
     * This method sends the message (that the client(chat person) writes to the user)
     * @param x
     * @throws NullPointerException
     * @throws IOException 
     */
    public void SendChat(String x) throws NullPointerException{
            pw.print("CHAT:"+x);
            pw.flush();
        /*  pw.println(2);
            pw.flush();
            pw.println(SimpleController.currentClientId);
            pw.flush();
            pw.println(x);
            pw.flush(); 
        */
    }
    public int sendCommando(int id) throws IOException{
        System.out.println("Jeg sender"+ id);
        pw.println(id);
        pw.flush();
        /*
         * this part of the program sends a command to the server if the command is 1 then 1 is = Connect.
         * the program then ask the server is the server is full or is it ok to connect? 
         * if the response is not 10 then the program will allow a connection to happen the return type will be the Id of which 
         * the chat person becomes!
         */
        // should the method return 0 the Application will do NOTHING!
        switch (id) {
        case 1:
    int k = reciveCommando();
            if (k== 10) {
                return 10;
            }else if (k < 3) {
                System.out.println("returned k" + k);
                return k;
            }else {

            return 10;
            }
            /*
             * Closes the connection with the server!
             */
        case 3:

            socket.close();
            return 0;

        case 5:
            int y  = reciveCommando();
            return y;

        case 8:
            return 8;
        default:
            return 0;
        }

    }
    /*
     * this method recives a command from the server! the comands can be found in the ChatCommands.txt
     * returns the command as an integer!
     */
    public int reciveCommando() throws IOException{
        Integer i = input.nextInt();
        return i;
    }
    /**
     * Gets a String response from the server. This method i used to create other users and give them the correct username.
     * 
     * @param i
     * @return
     * @throws IOException
     */
    public String getStringResponse(int i) throws IOException {
        pw.print(i);
        pw.flush();
        String x = input.nextLine();
        return x;

    }
/*
 * Work in progress - client getter og setter methoder!
 */

public Socket getSocket(){
    return socket;
}
public Scanner getInput(){
    return input;
}
public PrintWriter getPw(){
    return pw;
}
public int getClientId(){
    return clientId;
}

public void setClientId(int i ){
    clientId = i;
}
public String reciveChat(){
        return getInput().nextLine();

}
public String reciveString(){
    String x =input.next();
    return x;
}
public void sendString(String x){
    pw.println(x);
    pw.flush();
}



}

服务器代码

    import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;


public class Server extends Thread {

    private Socket connection;
    private PrintWriter pw;
    private Scanner input;
    private ServerInformation info = new ServerInformation();
    private ChatPerson p;

    public Server(Socket connection, PrintWriter pw, Scanner input){
        this.connection = connection;
        this.pw = pw;
        this.input = input;
    }

    @Override
    public void run() {
        while (connection.isConnected()) {
            if (input.hasNextInt()) {
                System.out.println("Det var sgu da en int");
                int i = getInput().nextInt();
                System.out.println(i);
                checkCommand(i);    
            }else if (input.hasNext()) {
                System.out.println("det var ikke en int");
                String inString = input.nextLine();
                System.out.println(inString);
                chatCase(inString);
            } 
        }


    }
    private void chatCase(String x) {
        String k =x.substring(6 , x.length());
        System.out.println("k "+k);
        pw.print(x);

        pw.flush();
    }

    private void checkCommand(int i) {
        System.out.println("i "+i);
        switch (i) {
        // this case accepts the connection and creates a new user;
        case 1:


int id = info.getNextID();
        pw.println(1);
        pw.flush();
        pw.println(id);
        pw.flush();
        p = new ChatPerson(id, input.next());
        info.addToList(p);
        break;

        // this is the chat case virker ikke endnu
    case 2:
        int clientID = input.nextInt();
        String x = reciveString();
        System.out.println(x);
        pw.println(clientID);
        pw.flush();
        pw.print(x);
        pw.flush();
        break;
    // this case sends information about other chat users to the client
    case 5:
        pw.println(5);
        pw.flush();
        pw.println(info.getList().size());
        pw.flush();
        for (int j = 0; j < info.getList().size(); j++) {
            pw.println(info.getList().get(j).getId());
            System.out.println("info.get "+info.getList().get(j).getId());
            pw.flush();
            pw.println(info.getList().get(j).getName());
            pw.flush();
        }
        break;

    case 8:
        pw.println(8);
        pw.flush();
        break;
    default:
        break;
    }

}

private String reciveString() {
    if (input.next().contains(" ")) {
        String x = input.nextLine();
        return x;
    }
    return input.next();
}

public Socket getConnection(){
    return connection;
}
public PrintWriter getPw(){
    return pw;
}
public Scanner getInput(){
    return input;
}




}

我希望有人能够帮助我,因为如果你需要更多信息,这对我来说是一个很大的问题,请尽快评论和提供

1 个答案:

答案 0 :(得分:3)

你必须重做你的程序。

  1. GUI元素应仅在GUI线程(EDT)内更新,而不是从独立线程更新。

  2. 客户端连接应划分为2个弱连接部分:发送消息并接收消息。接收应该是一个单独的线程,发送可以是一个线程或一个类。

  3. 当接收线程已阅读消息时,它会使用SwingUtilities.invokeLater(Runnable)将其发送给EDT。例子可以在其他地方找到。

  4. 当用户输入文本时,文本将直接发送到套接字,或者在队列中排队,然后由发送线程处理(如果有)。