2010-02-19 100 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来加快速度。