0

我有一个使用套接字进行服务器/客户端通信的简单程序。服务器类包含run()方法,该方法有无限循环等待套接字接受。

无论如何,我在构造函数中编写了一个代码来终止处理关闭,

 this.addWindowListener(new java.awt.event.WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent windowEvent) {
        System.out.println("Close operation server done");
        toClient.println("Bye");
        closeStreams();
        socket = null;
        serverSocket = null;
        System.exit(0);
    }
});

当我阅读该方法 windowClosing(WindowEvent e)的 API 时,它说:

当窗口正在关闭时调用。此时可以覆盖关闭操作。

它说一个窗口正在关闭的过程中。但是 run() 方法内部的循环仍然获得控制权,由于程序的逻辑,不会结束,所以不会关闭窗口(实际上是关闭了 GUI),但处理仍在幕后进行。

更新:

run()方法:

public void run()
{
    try
    {
        while (true)
        {
            idle = true;
            System.out.println("System is running");
            socket = serverSocket.accept();
            System.out.println("Client accepted on server side");
            openStreams();
            toClient.println("Hello: server is connected " + serverAddress.getLocalHost().toString());
            processClient();
            //   closeStreams();
        }
    } catch (Exception e)
    {
        System.out.println("Error accepting server " + e);
    }
}

processClient()方法:

 public void processClient() throws IOException
    {
        System.out.println("Porcessing start");
        String line = fromClient.readLine();
        try
        {
            while (!(line.equals("Bye")))
            {
                textToReceive.append("He: " + line + newline);
                line = fromClient.readLine();
            }
            closeStreams();

        } catch (IOException ex)
        {
            System.out.println("Error reading from client " + ex);
        }
    }

如何正确强制程序运行?

更新 2:整个工作服务器类:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

/**
 *
 * @author S
 */
public class ChatServer extends JFrame
{

    private InetAddress serverAddress;
    private Socket socket;
    private ServerSocket serverSocket;
    private InputStream is;
    private OutputStream os;
    private BufferedReader fromClient;
    private PrintWriter toClient;
    private JButton send;
    private JPanel uperPanel;
    private JPanel midPanel;
    private JPanel downPanel;
    private JTextArea textToSend;
    private JTextArea textToReceive;
    private JLabel addressL;
    private final int port = 5555;
    private boolean idle = false;
    private int timeout = 3000;
    public static String newline = System.getProperty("line.separator");

    private ChatServer()
    {
        this.setGUI();
        this.setVisible(true);
        try
        {
            serverSocket = new ServerSocket(port);
            this.run();
        } catch (IOException ex)
        {
            Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex);
        }

        this.addWindowListener(new java.awt.event.WindowAdapter()
        {
            @Override
            public void windowClosing(java.awt.event.WindowEvent windowEvent)
            {
                idle = true;
                closeStreams();
                socket = null;
                serverSocket = null;
                System.exit(0);
            }
        });
    }

    public void run() throws IOException
    {
        try
        {
            while (true)
            {
                System.out.println("System is running");
                socket = serverSocket.accept();
                System.out.println("Client accepted on server side");
                openStreams();
                toClient.println("Hello: server is connected " + serverAddress.getLocalHost().toString());
                processClient();
                //   closeStreams();
            }
        } catch (java.net.SocketTimeoutException ee)
        {

            closeStreams();
            System.out.println(ee);


        } catch (Exception e)
        {
            System.out.println("Error accepting server " + e);
        }

    }

    public void processClient() throws IOException
    {
        System.out.println("Porcessing start");
        String line = fromClient.readLine();
        try
        {
            while (!(line.equals("Bye")))
            {
                textToReceive.append("He: " + line + newline);
                line = fromClient.readLine();
            }
            closeStreams();

        } catch (IOException ex)
        {

            System.out.println("Error reading from client " + ex);

        }
    }

    private void setGUI()
    {

        this.setSize(375, 314);


        send = new JButton("send");

        try
        {
            addressL = new JLabel("My Server address: " + serverAddress.getLocalHost().toString()
                    + "  Port: " + this.port);
        } catch (Exception e)
        {
            System.out.println("Unknown Host problem " + e);
        }

        textToReceive = new JTextArea(12, 30);
        textToReceive.setLineWrap(true);
        JScrollPane recievedScrolledText = new JScrollPane(textToReceive);
        recievedScrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        textToReceive.setEditable(false);


        textToSend = new JTextArea(3, 25);
        textToSend.setLineWrap(true);
        JScrollPane sentScrolledText = new JScrollPane(textToSend);
        sentScrolledText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        textToSend.setEditable(true);

        uperPanel = new JPanel();
        midPanel = new JPanel();
        downPanel = new JPanel();

        uperPanel.add(addressL);


        midPanel.add(recievedScrolledText);
        downPanel.add(sentScrolledText);
        downPanel.add(send);

        Container c = getContentPane();
        c.setLayout(new BorderLayout());
        c.add(uperPanel, "North");
        c.add(midPanel, "Center");
        c.add(downPanel, "South");

        send.addActionListener(new ButtonWatch());
        textToSend.addKeyListener(new KeyWatch());
    }

    private void openStreams() throws IOException
    {

        is = socket.getInputStream();
        fromClient = new BufferedReader(new InputStreamReader(is));
        os = socket.getOutputStream();
        toClient = new PrintWriter(os, true);
        System.out.println("open stream is open on server");
    }

    private void closeStreams()
    {
        try
        {

            if ((toClient != null) && (os != null)
                    && (fromClient != null) && (is != null)
                    && (fromClient != null) && (socket != null))
            {
                toClient.close();
                os.close();
                fromClient.close();
                is.close();
                socket.close();
            }


        } catch (IOException ex)
        {
            System.out.println("Problem closing streams " + ex);
        }
    }

    private class KeyWatch extends KeyAdapter
    {

        public void keyPressed(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_ENTER)
            {
                String line = textToSend.getText();
                textToSend.setText("");
                toClient.println(line);
                textToReceive.append("You: " + line + newline);
            }
        }

        public void keyReleased(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_ENTER)
            {
            }
        }

        public void keyTyped(KeyEvent e)
        {
            if (e.getKeyCode() == KeyEvent.VK_ENTER)
            {
            }
        }
    }

    private class ButtonWatch implements ActionListener
    {

        @Override
        public void actionPerformed(ActionEvent e)
        {
            Object buttonPressed = e.getSource();

            if (buttonPressed == send)
            {
                String line = textToSend.getText();
                textToSend.setText("");
                toClient.println(line);
                textToReceive.append("You: " + line + newline);

                System.out.println("send to client " + line);
            }

        }
    }

    public static void main(String[] args)
    {
        ChatServer s = new ChatServer();
        s.setVisible(true);
    }
}

现在如何在关闭后终止它。

4

2 回答 2

1

Change your server loop to be not infinite.

volatile boolean runFlag = true;
while (runFlag) {
  //do server stuff
}

and get your closing method to flag the server to stop.

this.addWindowListener(new java.awt.event.WindowAdapter() {
  @Override
  public void windowClosing(java.awt.event.WindowEvent windowEvent) {
    System.out.println("Close operation server done");
    toClient.println("Bye");
    closeStreams();
    runFlag = false;
  }
});

You might want to move the stream closing stuff to after the main server loop so that any stuff that is in progress gets finished and you don't interrupt anything currently in progress.

于 2012-11-30T10:33:17.707 回答
1

-那么它更好地用于Executor跨越线程。

-然后使用cancel(true)withsubmit()方法中断这个特定的线程。

-如果你想Thread直接去,那么你可以使用interrupt()orinterrupted()方法来打断thread.

于 2012-11-30T10:26:56.810 回答