1

ソケットを使用したサーバー/クライアント通信用の簡単なプログラムがあります。サーバークラスにはメソッドが含まれています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);
    }
});

メソッド のAPIを読むと、次のように表示windowClosing(WindowEvent e)されます。

ウィンドウを閉じる途中で呼び出されます。この時点で、クローズ操作をオーバーライドできます。

それはウィンドウが閉じられている途中であると言います。ただし、run()メソッド内のループは引き続き制御を取得し、プログラムのロジックにより終了しないため、ウィンドウは閉じられません(実際にはGUIは閉じられます)が、処理はバックグラウンドで機能します。

プログラムの実行を正しく強制するにはどうすればよいですか?

動作中のサーバークラス全体:

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.*;


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);
    }
}

(x)閉じるアイコンをクリックした後に正しく終了する方法を説明します。

4

3 に答える 3

2

また:

setDefaultCloseOperationCloseListenerウィンドウイベントハンドラーを見ましたか?

于 2012-11-30T19:29:05.560 に答える
1

を使用して、スレッドThreadとして設定します。daemonここで、コードの最初の数行を変更しました。

public class ChatServer extends JFrame implements Runnable
{
    private ChatServer()
    {
        this.setGUI();
        this.setVisible(true);
        try
        {
            serverSocket = new ServerSocket(port);
            Thread accept = new Thread(this);
            accept.setDaemon(true);
            accept.start();
        } catch (IOException ex)
        {
            Logger.getLogger(ChatServer.class.getName()).log(Level.SEVERE, null, ex);
        }
于 2012-11-30T19:19:15.847 に答える
0

ハンドラーでサーバーソケットserverSocket.close()を閉じます。windowClosingこれにより、acceptループがスローSocketExceptionされ、中断されます。あなたはそれを捕まえて、優雅なシャットダウンをするために処理することができます。

于 2012-11-30T19:26:41.097 に答える