2012-07-15 83 views
3

我正在嘗試使用DatagramSocket和DatagramPacket類來製作服務器程序,但我當前的代碼使用了一個醜陋的while循環,它在服務器運行時也凍結了我的程序,但服務器正常運行並沒有問題。無論如何,代碼如下。無論如何,我可以使用不同於while循環的東西,或防止while循環阻止程序中的任何其他代碼執行?如何在不使用while循環的情況下運行服務器?

protected void run() { 
    try { 
     socket = new DatagramSocket(port); 
     socket.setBroadcast(true); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     stopServer(); //stop the server 
     return; 
    } 
    while(isRunning()){ //hate this loop 
     try { 
      byte[] buf = new byte[256]; 
      DatagramPacket packet = new DatagramPacket(buf, 256); 
      socket.receive(packet); 
      DatagramPacket serverPacket; 
      byte[] serverBuf; 
      byte hb = 0; 
      byte lb = packet.getData()[0]; 
      int e = ((int)hb<<8)|((int)lb&0xFF); //translate byte to int 
      switch(e) { 
       case 2: 
        //do something 
        break; 
       case 5: 
        //do something 
        break; 
       case 7: 
        //do something 
        break; 
       default: 
        //default stuff 
        break; 
      } 
     } catch (Exception e) { 
      System.out.println("Fatal Server Error:"); 
      e.printStackTrace(); 
      stopServer(); //stop the server 
      return; //stop the method 
     } 
    } 
} 
+0

[threads](http://docs.oracle.com/javase/tutorial/essential/concurrency/)? – 2012-07-15 13:15:32

回答

8

你應該把它放在一個新的線程中。接收數據包的過程包括同步IO,所以它總是會阻止它的運行哪個線程。

要澄清,這不是while循環本身,使程序等待的其餘部分。這是socket.receive()調用。

+0

另外,請記住你應該在你的循環中的關鍵位置檢查Thread.currentThread()。isInterrupted()。這允許管理這個線程實例的任何人(主程序或其他)調用thread.interrupt()並實際關閉你的服務器。否則,我懷疑socket.receive()將是唯一可以被中斷的部分。另外,每次從「receive()」方法獲得一個套接字時,您應該將套接字發送到一個ExecutorService實例進行處理,否則您已經編寫了一個單線程服務器(儘管這可能是您的意圖)。 – Matt 2012-07-15 19:09:06

4

我懷疑,你可以擺脫循環的,因爲你,從邏輯上講,打算您的服務器「服務」的多個請求。每個請求將在服務器循環的一次迭代中提供。現在

,這是習慣,你的服務器將只關心收到請求,將它們分派到一個線程池來處理。

因此,您不要讓服務器線程擔心給定請求的處理。基本上,因爲如果您的服務器正忙於處理請求,那麼在此期間它不能參加到達其端口的任何其他請求。

的建議是,接收的數據包,和immediatelly所接收的數據傳遞到另一個線程進行處理。

這,顯然,不會意味着移除相關的循環,正如我所說,除非你打算爲來自您的客戶只有一個請求(相當不可能的情況)是不可能的。這將保證可以獨立處理請求,並且處理不會延遲到達服務器端口的其他請求。

0

我建議使用Apache Mina來管理您的流量和網絡通信。

它是專爲這個特別並提供Reactor design pattern的實現,這可能是您的應用程序更好的設計選擇。

相關問題