2013-03-12 22 views
1

因此,我正在爲IRC服務器,並且我添加了一個配置屏幕,您可以在其中編輯它正在使用的端口,但我必須重新調整Listen類效果,所以我有這個在我的配置類:Java - 重新加載類時關閉套接字

Listen.closePorts(); 
new 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()如果端口是相同的,因爲這是在港口使用。

這麼久以來,我怎麼才能重新教育班級和使用新的端口之前關閉插座?

下面是完整的例外是trows:

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) 
+0

是否拋出任何異常?它需要多長時間? – 2013-03-12 19:53:59

+0

它不是拖延異常,它只是掛起,過了一段時間,我只是強制關閉應用程序在任務管理器 – Snakybo 2013-03-12 19:55:48

+0

它看起來像你試圖關閉同一個套接字兩次?您的finally塊會關閉套接字,如果您在此之後調用closePorts,可能會導致問題。 – Max 2013-03-12 19:56:08

回答

0

socket變量只有在客戶端發出請求後纔會分配。如果您在此之前致電closePorts(),程序仍會等待socket = serverSocket.accept();,並且socket.close()將拋出NullPointerException,因爲socket仍然爲空。對於ServerSocket.accept()的描述,請參閱http://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#accept()

+0

中進行編輯所以,如何阻止它等待客戶端連接? – Snakybo 2013-03-12 20:22:04

+0

您可以在*'socket = serverSocket.accept()'之前調用'setSoTimeout(毫秒)'*。這將導致它只在指定的時間段內阻塞,之後它將引發一個'SocketTimeoutException'。請參閱http://docs.oracle。COM/JavaSE的/ 7 /文檔/ API/JAVA /淨/ ServerSocket.html#setSoTimeout(INT)。 – Alex 2013-03-12 20:31:13

1

沒有提供一個直接的解決方案,但沒有引發異常,因爲你的代碼正在吞噬它們。空的抓塊從來都不是好習慣。至少,使用e.printStackTrace()打印捕獲到的異常的堆棧跟蹤

+0

好吧,我用e.printStackTrace試了一下;它帶有java.lang.NullPointerException異常,但套接字應該運行/正在等待消息,因此它不能爲空? – Snakybo 2013-03-12 20:09:12

+0

你能展示完整的痕跡嗎?您是否能夠在引起問題的線路上進行調試? – JamesB 2013-03-12 20:10:40

+0

我將在OP – Snakybo 2013-03-12 20:13:53

0

這裏沒有類重新加載,也不需要關閉現有客戶端接受的套接字。只需關閉ServerSocket並在新端口上重新創建即可。