2010-02-19 71 views
1

我對Java很陌生,我試圖修改一個套接字服務器的例子來爲基於Flash的遊戲提供動力。爲了允許Flash連接到服務器,我需要提供一個策略文件。如何關閉Java中的線程?

我以前從來沒有編碼的服務器應用程序,所以我不是太熟悉,這就需要發生的事情。

無論如何,所以它輸出的文件,但由於某種原因它這樣做10次我都做到了。

我需要關閉線程,然後再繼續執行。以下是我的代碼,並在需要關閉該線程的地方發表評論。

import java.io.*; 
import java.net.*; 
import java.util.Random; 

public class Main { 

    private static int port=4041, maxConnections=0; 
    // Listen for incoming connections and handle them 
    public static void main(String[] args) { 
    int i=0; 

    try{ 
     ServerSocket listener = new ServerSocket(port); 
     Socket server; 

     while((i++ < maxConnections) || (maxConnections == 0)){ 
     doComms connection; 

     server = listener.accept(); 
     doComms conn_c= new doComms(server); 
     Thread t = new Thread(conn_c); 
     t.start(); 
     } 
    } catch (IOException ioe) { 
     System.out.println("IOException on socket listen: " + ioe); 
     ioe.printStackTrace(); 
    } 
    } 

} 

class doComms implements Runnable { 
    private Socket server; 
    private String line,input; 

    doComms(Socket server) { 
     this.server=server; 
    } 

    public void run() { 

     char EOF = (char)0x00; 
     input=""; 

     try { 
     // Get input from the client 
     DataInputStream in = new DataInputStream (server.getInputStream()); 
     PrintStream out = new PrintStream(server.getOutputStream()); 

     while((line = in.readLine()) != null && !line.equals(".")) { 
      input=input + line; 
      if(line.trim().equals("h")){ 

       out.println("h"+EOF); 

      } 
      else if(line.trim().equals("i")){ 

       Random randomGenerator = new Random(); 
       int randomInt = randomGenerator.nextInt(4); 

       out.println("b"+randomInt+EOF); 


      } 
      else if(line.trim().equals("c")){ System.out.println("Player collision.");} 
      else if (line.trim().equals("<policy-file-request/>")) { 
      out.println("<?xml version=\"1.0\"?>\n<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\"><cross-domain-policy>\n<site-control permitted-cross-domain-policies=\"all\"/>\n<allow-access-from domain=\"*\"/>\n</cross-domain-policy>"+EOF); 
      System.out.println("Responded to policy request"); 
      // I need to close the thread/disconnect the client here. 
      } 
      else System.out.println("Unknown command: "+line.trim()); 

     } 
     server.close(); 
     } catch (IOException ioe) { 
     System.out.println("IOException on socket listen: " + ioe); 
     ioe.printStackTrace(); 
     } 
    } 
} 

另外,在NetBeans中還有一個額外的東西,它強調了「import java.io. *;」並說不正確的軟件包,但它仍然正常工作。

編輯: 我已經發現,它發送它10次的原因是它在單次發送操作中接收10行。我嘗試添加「返回」;在它發送策略XML的地方,但它似乎仍然不是客戶端。我也應該注意到,我打算這是一個多人遊戲服務器,所以我需要保持打開的套接字並關閉一個線程。

+3

類應該是Java中的UpperCamelCase而不是doComms。它應該是一個名詞,doComms是一個動詞。 – 2010-02-19 21:17:55

回答

3

乍一看,你run()方法看起來應該正常終止。我懷疑你的循環:

while((i++ < maxConnections) || (maxConnections == 0)){ 

由於maxConnections被初始化爲0,並且永遠不會增加,循環似乎無限運行,並創造了許多線程 - 可能多達插座可以接受的聽衆。然後它從IOException的循環中爆發出來。這是真的發生了什麼?

更新:顯然不是...的想法現在。

+2

不,它應該阻止listener.accept併爲每個請求創建一個線程。 – abc 2010-02-19 21:16:28

+0

+1閱讀所有代碼 – stacker 2010-02-19 22:20:54

0

您的代碼有意義。你的意見是什麼?如果你有10行說「<策略文件請求/ >」,那麼的確會打印文件10次。如果你有那些條款,那麼所有其他的呢?在每一個你打印的東西+ EOF,但肯定你只是想打印一個響應每個請求。您的'輸入'變量也未被使用。

+0

我需要Flash客戶端保持連接,因爲它是一個遊戲,這些是它的基本多人遊戲包。不幸的是,閃存要求我提供來自同一主機的策略文件以允許進一步的通信。 – Alex 2010-02-19 22:21:42

0

從doComms.run()返回後,線程將會死亡。請大寫Java類名稱的開頭:它應該是DoComms,只是爲了讓代碼更易於遵循其他Java程序員。

要關閉連接,你的電話server.close()應該做它。爲了確保輸出完全首先發送,你應該叫close()flush()PrintStream你打電話之前Socket.close()

您要發送什麼輸入?看起來好像你只從客戶端發送一次<policy-file-request/>,你只會得到一次文件。

不確定NetBeans,但它是否抱怨說您的.java文件的頂部沒有指定package?嘗試添加下面的包聲明,與路徑的相對到NetBeans項目的頂部:

package my.path.to.this.directory; 
0

我建議在調試器中運行在服務器和客戶端,並通過加強執行,看看會發生什麼每個時間點。這將幫助您確認每個點的預期值。 Eclipse和其他Java IDE有非常好的(和易於使用的)調試器。

至於你的代碼:

  1. 我會爲每個 循環迭代做line.trim()一次,而不是 裝飾()'荷蘭國際集團反覆 不必要創造額外 對象。
  2. 確保客戶端和服務器都在每個請求/響應後flush()Socket的OutputStream。如果套接字的OutputStream尚未刷新,則連接另一端的InputStream可能會阻塞等待輸入,而OutputStream塊將等待填充其緩衝區。
  3. 客戶端 中的代碼是什麼樣的?你確定它是 發送空或「。」關閉 連接?在檢查「。」之前是否需要修剪()?
  4. 正如其他人所提到的,您的代碼並不遵循典型的Java編碼約定。我建議通過閱讀已發佈的code conventions for Java來加快速度。