2013-01-16 20 views
1

我使用套接字編寫多個客戶端服務器。我寫了簡單的客戶端 - 服務器應用程序,並一切正常,但是當我試圖將其更改爲多客戶端應用程序,我得到了異常,當我開始客戶端:多臺客戶機 - 在Java服務器應用程序 - 在java中

Exception in thread "pool-1-thread-1" java.lang.NullPointerException 
    at MiniSerwer.run(Serwer.java:110) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:679) 

我還有兩節課(線程 - InWorker和外包工輸入和輸出)。

Serwer.java(不InWorker和外包工):

public class Serwer { 
Serwer(int port) { 
ServerSocket serversocket=null; 
ExecutorService exec= Executors.newCachedThreadPool(); 

    try { 
     serversocket=new ServerSocket(port); 
    } catch (IOException e) { 
     e.printStackTrace(); 
} 
    while(true) { 
    Socket socket=null; 
    try { 
     socket = serversocket.accept(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    exec.execute(new MiniSerwer(socket)); // create new thread 
     } 
} } 

MiniSerwer - 輔助類來創建線程擁有人人客戶端

class MiniSerwer implements Runnable{ 

    Socket socket=null; 
    ExecutorService exec=null; 
    ObjectOutputStream oos=null; 
    ObjectInputStream ois=null; 

    MiniSerwer(Socket socket) { 
     this.socket=socket; 
     try { 
      oos=new ObjectOutputStream(socket.getOutputStream()); 
      oos.flush(); 
      ois=new ObjectInputStream(socket.getInputStream()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void run() { 
     while(true) { 
      exec.execute(new InWorker(socket, ois)); // input stream 
      exec.execute(new OutWorker(socket, oos)); //output stream 
      Thread.yield(); 
     } 
    } 
} 

更改我的程序,但它仍然無法正常工作。任何其他建議?

服務器:

public class Serwer implements Runnable{ 

ServerSocket serversocket=null; 
ExecutorService exec= Executors.newCachedThreadPool(); 
int port; 

Serwer(int port) { 
    this.port=port; 
} 

public void run() { 
    try { 
     serversocket=new ServerSocket(port); 
     while(true) { 
      Socket socket=null; 
      try { 
       socket = serversocket.accept(); 
       exec.execute(new MiniSerwer(socket)); // create new thread 
      } catch (IOException e) { 
       e.printStackTrace(); 
       throw new RuntimeException(e); 
      } 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
} 
} 

public static void main(String[] args) { 
    int port; 
    Scanner in = new Scanner(System.in); 
    System.out.println("Enter the port:"); 
    port = in.nextInt(); 
    ExecutorService exec=Executors.newCachedThreadPool(); 
    exec.execute(new Serwer(port)); 
} 
} 

MiniSerwer:

class MiniSerwer implements Runnable{ 

    Socket socket=null; 
    ExecutorService exec=Executors.newCachedThreadPool(); 
    ObjectOutputStream oos=null; 
    ObjectInputStream ois=null; 

    MiniSerwer(Socket socket) { 
     this.socket=socket; 
    } 

    public void run() { 
     try { 
      oos=new ObjectOutputStream(socket.getOutputStream()); 
      oos.flush(); 
      ois=new ObjectInputStream(socket.getInputStream()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     while(true) { 
      exec.execute(new InWorker(socket, ois)); // input stream 
      exec.execute(new OutWorker(socket, oos)); //output stream 
      Thread.yield(); 
     } 
    } 
} 

我有很多例外,當我試圖從客戶端發送消息給服務器。

2秒。在服務器端連接後(我不發送任何東西):

Exception in thread "pool-2-thread-1" java.lang.OutOfMemoryError: unable to create new native thread 
    at java.lang.Thread.start0(Native Method) 
    at java.lang.Thread.start(Thread.java:657) 
    at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:943) 
    at java.util.concurrent.ThreadPoolExecutor.processWorkerExit(ThreadPoolExecutor.java:992) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:679) 
+0

那麼,你的線程中有一個空指針異常。但我無法單單告訴你這些信息。有些東西沒有像應該的那樣初始化。 – ATaylor

+0

作爲一個方面說明,在構造函數中運行服務器邏輯是非常糟糕的做法。你會想把它移出到另一種方法。我建議實現Runnable接口,並將邏輯移至run方法。 – Perception

回答

2

您的執行器服務在您的MiniSerwer類中從未初始化。這是你NPE的根本原因。

但是就像我在我的評論中提到,你不應該做在它的構造函數的所有Serwer邏輯。對象永遠不會完全初始化,因爲您永遠不會退出構造函數。使整個班級Runnable並將該邏輯移至重寫的run方法。然後添加一個main方法用於實際實例化/運行服務器。

另外,在您的MiniSerwer中,您的流初始化可能會失敗。在運行方法中使用它們之前,您需要驗證流是否爲空。或者只是將它們的初始化邏輯移動到run方法的開頭。

編輯

你也有你的MiniSerwer實現中的錯誤,你生成線程無限多以加工物體輸入和輸出流:

while(true) { 
    exec.execute(new InWorker(socket, ois)); // input stream 
    exec.execute(new OutWorker(socket, oos)); //output stream 
    Thread.yield(); 
} 

你要麼耗盡線程,內存不足或兩者兼而有之。說實話,你的解決方案是過度設計的,我懷疑進出工人真的需要按照你現在的方式分開。

+0

我做了你的建議,但程序仍然無法正常工作。我將它們添加到第一篇文章。還有其他建議嗎? – user1518451

+0

請在您的問題中添加例外。 – Perception

+0

我在第一篇文章中添加了例外情況。 – user1518451

0

千萬別做這樣可怕的事情。在下面你忽略例外兩次代碼:

首先忽略:

try { 
    serversocket=new ServerSocket(port); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

serversocket後可能null作爲

之前

和第二忽略:

while(true) { 
    Socket socket=null; 
    try { 
     socket = serversocket.accept(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    exec.execute(new MiniSerwer(socket)); // create new thread 
} 

try...catchsocket後還可以像以前一樣null

這兩件事都可能導致NullPointerException

修復這一切,如:


UPD:這一個:while(true) {...}也是很可怕的事情。但是,讓我們把這個問題放在括號後面。


+0

我的壞。謝謝,但它不能解決我的問題。 – user1518451

相關問題