3

我必须编写一个 java 客户端-服务器应用程序来模拟车库中的汽车。在客户端,我将有一个带有 2 个按钮的小框架 - 一个用于进入车库,另一个用于离开它。在下面的代码中,你可以看到我做了什么。但是当我运行它并按下回车按钮时,我的框架卡住了。任何想法我的代码有什么问题?程序没有产生错误。

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

class Form  extends JFrame implements ActionListener{

    JButton btnEnter = new JButton("Enter Garage");;
    JButton btnLeave = new JButton("Leave Garage");;
    Client client = new Client();

public void start(){

        FlowLayout layout = new FlowLayout();
        layout.setAlignment(FlowLayout.CENTER);
        layout.setHgap(25);
        layout.setVgap(85);

        btnEnter.addActionListener(this);
        btnLeave.addActionListener(this);

        JPanel content = new JPanel();
        content.setLayout(layout);
        content.add(btnEnter);
        content.add(btnLeave);

        setContentPane(content);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Welcome to the Garage");
        setLocationRelativeTo(null);

        setSize(500,250);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent e1) {

        if(e1.getSource().equals(btnEnter)){

                client.enter();

        }

        if(e1.getSource().equals(btnLeave)){

                client.leave();

        }

    }
}

public class Client{

    Socket socket;
    PrintWriter out;
    BufferedReader in;
    String name = "Client";

    Client() {


    }


    public void connect() throws IOException {
        String server = null;
        try {
            InetAddress addr = InetAddress.getByName(server);
            socket = new Socket(addr, 8080);
            in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                    socket.getOutputStream())), true);

        } catch (UnknownHostException e) {
            e.printStackTrace();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
            socket.close();
        }
    }

    public void enter(){
        String stat = "";

        try{
            connect();
        } catch(IOException e){
            e.printStackTrace();
        }

        send("Client");
        send("init_car");

        //Taking Garage Stage
        send("garage1");
        try{
            while(!stat.equals("garage_taken")){
                System.out.println("taking??");
                send("chk_stat");
                stat = receive();
                System.out.println(stat);
                Thread.sleep(500);
            }
        } catch(IOException e){
            e.printStackTrace();
        } catch(InterruptedException e){
            e.printStackTrace();
        }

    }

    public void leave(){

        String stat = "";

        send("garage2");
        try{
            while(!stat.equals("garage_released")){
                send("check_status");
                stat = receive();
                Thread.sleep(500);
            }
        } catch(IOException e){
            e.printStackTrace();
        } catch(InterruptedException e){
            e.printStackTrace();
        }


        send("/quit");

    }

    public void send(String s) {
        if (s.equals("/quit")) {
            //g.serv.append("Closing connection with server...\n");
            out.print("/quit");
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            //g.serv.append("Connection closed. You can close the window now.\n");
            System.exit(0);

        } else
            out.println(s);
    }

    public String receive() throws IOException {
        String s = "";
        try {
            s = in.readLine();
        } catch (IOException e) {
            socket.close();
        }
        return s;
    }

    public static void main(String args[]) {

        new Form().start();
/*      
        try {
            client.start();
        }catch (InterruptedException e){
            e.printStackTrace();
        }*/
    }

}

请帮我解决一下这个。我花了很多时间试图了解出了什么问题,但是由于我没有使用 Java 的经验,所以我找不到解决方案:(


我将在这里发布我的其余代码。可能这会有所帮助:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Timer;
import java.util.TimerTask;

class OneClient extends Thread {
    private Socket clSocket;
    private BufferedReader in;
    private PrintWriter out;
    private String name="";
    private String carStatus = "";
    private Garage garage;

    OneClient(Socket s, Garage gr) throws IOException{
        clSocket = s;
        garage = gr;
        in = new BufferedReader(new InputStreamReader(clSocket.getInputStream()));
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(clSocket.getOutputStream())),true);
        start();
    }

    public void run(){

        try{
            while(true){
                String str = in.readLine();
                if(null==str || str.equals("/quit")) {
                    break;
                }

                if(name.equals("")) {
                    name=str;
                    System.out.println("\nNew name for a client: " + name);
                    Thread.currentThread().setName(name);
                } else {

                    if(str.equals("init_car")){
                        System.out.println(name + " is comming to the garage.");
                        carStatus = str;

                    } else if(str.equals("garage1")){
                        carStatus = str;
                        System.out.println(name + " try to enter the garage...");
                        str = garage.takeGarage(name);
                        carStatus = str;


                    } else if(str.equals("garage2")){
                        carStatus = str;
                        str = garage.releaseGarage();
                        carStatus = str;


                    } else if(str.equals("check_status")){
                        out.println(carStatus);

                    }

                }
            }
        } catch(IOException e){
        } finally {
            try{
                clSocket.close();
            } catch(IOException e){
                e.printStackTrace();
            }
        }
    }

}

public class Server {
    static final int PORT = 8080;
    static ServerSocket servSocket;
    static Garage garage;

    public static void main(String args[]) throws IOException{
        servSocket = new ServerSocket(PORT);
        Timer timer = new Timer();
        garage = new Garage();

        //TIMER TASK FOR BOTS
        timer.schedule(new TimerTask(){ 
                    public void run(){
                        new BotClient().runBots();
                    }
                }, 1000, 2000);


        System.out.println("Server is started!\n");
        try{
            while(true){
                Socket s = servSocket.accept();
                try{
                    new OneClient(s, garage);
                } catch(IOException e){
                    e.printStackTrace();
                    s.close();
                }
            }

        } finally {
            servSocket.close();
        }
    }
}







public class Garage {

    static boolean isGarageFree;
    static int counter=0;
    static int limit=30;

    Garage(){

       isGarageFree = true;

    }

    public  String takeGarage(String name){

        Thread.currentThread().setName(name);
        counter++;

        if(counter>limit) isGarageFree = false;
        else isGarageFree = true;

        while(!isGarageFree){
            try{
                Thread.sleep(500);
            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }

        try{
            Thread.sleep( (int) (Math.random()*500 + 1500) );
        } catch(InterruptedException e){
            e.printStackTrace();
        }

        System.out.println("Garage is taken by " + name + ".");
        System.out.println("\nThere are " + counter + " cars in the garage.\n");


        return "garage_taken";

    }

    public String releaseGarage(){

        try{
            Thread.sleep( (int) (Math.random()*5000 + 2000));
            System.out.println("\n" + Thread.currentThread().getName() + " is releasing the garage...");
        } catch(InterruptedException e){
            e.printStackTrace();
        }


        System.out.println("Garage is Released by " + Thread.currentThread().getName() + "!\n");
        counter--;
        System.out.println("\nThere are " + counter + " cars in the garage.\n");

        return "garage_released";
    }

}




import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

public class BotClient extends Thread{

    static int count = 0;

    BufferedReader in;
    PrintWriter out;
    InetAddress addr;
    Socket socket;
    String name = "";


    BotClient(){

    }

    void send(String s){
        if(s.length()==0){
            out.println("END");
            System.out.println("Closing...");
            try{
                socket.close();
            }
            catch (Exception expt){
                System.out.println(expt);
            }
            System.exit(0);
        }
        else out.println(s);

    }

    String receive() throws IOException{
        return in.readLine();        
    }

    public void init() throws IOException{
        count++;
        name = "Car " + count;
        this.setName(name);

        try{
            String server = null;
            InetAddress addr = InetAddress.getByName(server);
            socket = new Socket(addr, Server.PORT);
            in =  new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(new BufferedWriter(
                    new OutputStreamWriter(socket.getOutputStream())),true);

        }catch (Exception e){
            System.out.println("Exception: "+e);
            System.out.println("Closing...");
            socket.close();
        } 
    }

    public void run(){
        String stat = "";

        try{
            init();
        } catch(IOException e){
            e.printStackTrace();
        }

        send(name);
        send("init_car");

        send("garage1");

        try{
            while(!stat.equals("garage_taken")){
                send("check_status");
                stat = receive();
                Thread.sleep(500);
            }
        } catch(IOException e){
            e.printStackTrace();
        } catch(InterruptedException e){
            e.printStackTrace();
        }


        send("garage2");
        try{
            while(!stat.equals("garage_released")){
                send("check_status");
                stat = receive();
                Thread.sleep(500);
            }
        } catch(IOException e){
            e.printStackTrace();
        } catch(InterruptedException e){
            e.printStackTrace();
        }


        send("/quit");

    }

    public void runBots(){

        new BotClient().start();

        try{
            Thread.sleep(2000);
        }catch(InterruptedException e){
            e.printStackTrace();
        }

    }
}

我很确定问题出在 Frame 类的某个地方,因为如果我在不使用 JFrame 的情况下运行客户端类,它就可以工作。

4

1 回答 1

1

gui 冻结,因为您在leave函数中循环。如果您希望您的 GUI 保持响应,您应该考虑使用SwingWorker线程。但是,如果您的服务器没有发送正确的响应,这将无济于事,但至少 GUI 将保持更新和响应。

尝试这样的事情:

public void leave()
{
    SwingWorker<Void, Void> w = new SwingWorker<Void, Void>()
    {
        @Override
        protected Void doInBackground() throws Exception
        {
            String stat = "";

            send("garage2");
            try{
                while(!stat.equals("garage_released")){
                    send("check_status");
                    stat = receive();
                    Thread.sleep(500);
                }
            } catch(IOException e){
                e.printStackTrace();
            } catch(InterruptedException e){
                e.printStackTrace();
            }


            send("/quit");
            return null;
        }
    };
    w.execute();
       // here you can block to wait for the server to be done or show some info dialog, which in turn can be closed from the thread when done
 }
于 2013-08-02T18:01:21.200 回答