1

在过去的 5 天里,我试图找出为什么我的程序不起作用我在这里问了无数问题并得到了很好的回应,现在看来我已经找到了问题所在。

背景故事:

我有一个聊天程序,它分为两个单独的应用程序客户端和服务器。我们的想法是制作一个聊天程序,以便客户端拥有一个包含图片、一些标签和一些文本区域的 GUI。

每当客户端启动 Gui 节目并且用户能够点击按钮连接以尝试与服务器连接时,这就是我的程序中直接发生的事情,并且程序的这一部分工作正常:

** 正在按下连接按钮** 客户端发送到服务器: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;
}




}

我希望有人能够帮助我,因为这对我来说是个大问题,如果您需要更多信息,请发表评论,我会提供尽可能多的信息

4

1 回答 1

3

你必须重新设计你的程序。

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

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

  3. 当接收线程读取了一条消息后,它使用 . 将消息发送到 EDT SwingUtilities.invokeLater(Runnable)。示例可以在其他地方找到。

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

于 2012-10-13T14:10:20.473 回答