1

私は IRC 用のサーバーに取り組んでおり、使用しているポートを編集できる構成画面を追加しましたが、Listenそれを有効にするにはクラスを再初期化する必要があるため、構成クラスに次のようにします:

Listen.closePorts();
new Listen();

そして、これが私のListenクラスです:

package server.network;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import server.Server;
import server.gui.GUIMain;

public class Listen {
    private static Socket socket = null;
    private int port;

    public Listen() {
        try {
            port = Server.listenPort;
            @SuppressWarnings("resource")
            ServerSocket serverSocket = new ServerSocket(port);
            GUIMain.jta.append("\nServer Started and listening for messages on port " + port + ".\n");

            while(true) {
                socket = serverSocket.accept();
                InputStream is = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String msg = br.readLine();
                GUIMain.jta.append("Received message from client: " + msg + "\n");
            }
        } catch (Exception e) {
            GUIMain.jta.append("Port " + port + " already in use!\n");
        } finally {
            try {
                socket.close();
            }  catch(Exception e) { }
        }
    }

    public static void closePorts() {
        try {
            socket.close();
            GUIMain.jta.append("Server closed\n");
        } catch (IOException e) { }
    }
}

アプリケーションを起動すると、このクラスが実行され、指定されたポートでソケットが開かれますが、ここでポートを閉じようとすると:

public static void closePorts() {
    try {
        socket.close();
        GUIMain.jta.append("Server closed\n");
    } catch (IOException e) { }
}

それはハングアップしますsocket.close();

そして、コメントアウトしてクラスをリロードしようとして、ソケットを開いたままにしておくと、ポートが使用中のポートと同じ場合、Listen.closePorts();ハングするか実行されます。catch()

簡単に言えば、クラスを再インストールして新しいポートを使用する前にソケットを閉じるにはどうすればよいですか?

これが完全な例外です。

java.lang.NullPointerException
    at server.network.Listen.closePorts(Listen.java:44)
    at server.gui.GUISettings.actionPerformed(GUISettings.java:86)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)
4

3 に答える 3

1

直接的な解決策は提供しませんが、コードがすべてを飲み込んでいるため、例外はスローされません。空の catch ブロックは決して良い習慣ではありません。少なくとも、e.printStackTrace() を使用して、キャッチされた例外のスタック トレースを出力します。

于 2013-03-12T20:05:02.620 に答える
0

socket変数は、クライアントがリクエストを行うまで割り当てられません。それが起こる前に呼び出すとclosePorts()、プログラムは引き続き待機しsocket = serverSocket.accept();、null のままになるsocket.close()ため NullPointerException をスローします。socket

ServerSocket.accept() の説明については、http://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#accept()を参照してください。

于 2013-03-12T20:18:39.130 に答える
0

ここではクラスの再ロードは行われず、既存のクライアントが受け入れたソケットを閉じる必要はありません。ServerSocket を閉じて、新しいポートで再作成するだけです。

于 2013-03-12T22:49:59.690 に答える