繁体   English   中英

如何在Java中关闭线程?

[英]How to close a thread in Java?

我对Java还是很陌生,我正在尝试修改套接字服务器的示例以支持基于Flash的游戏。 要允许闪存连接到服务器,我需要提供一个策略文件。

我以前从未编写过服务器应用程序的代码,因此我对所需发生的事情不太熟悉。

无论如何,我已经做到了使其输出文件,但是由于某种原因,它执行了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的位置,但它似乎仍无法d / c客户端。 我还应该注意,比我打算将此服务器成为多人服务器要多,因此我需要保持套接字打开并仅关闭一个线程。

乍一看,您的run()方法看起来应该正常终止。 我怀疑你的循环:

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

由于maxConnections初始化为0且从未增加,因此循环似乎无限运行并创建许多线程-可能与套接字可以接受的侦听器一样多。 然后它通过IOException从循环中爆发出来。 这到底是怎么回事?

更新:显然现在还没有。

您的代码很有意义。 您的输入是什么? 如果您有10行说“ <policy-file-request />”,那么实际上它将打印文件10次。 那其他所有if子句呢? 在每个请求中,您都打印了一些内容+ EOF,但是您肯定只想为每个请求打印一个响应。 同样,您的“输入”变量也没有使用。

从doComms.run()返回后,线程将死亡。 请大写Java中类名的开头:应该是DoComms,只是为了使其他Java程序员更容易遵循这些代码。

要关闭连接,您对server.close()调用应该可以完成。 为了确保首先完全发送输出,应在调用Socket.close()之前在PrintStream上调用close()flush() Socket.close()

您要发送什么输入? 看起来,如果您仅从客户端发送一次<policy-file-request/> ,则只会获得一次文件。

不确定NetBeans,但是否抱怨您在.java文件顶部没有指定package 尝试添加以下程序包声明,其路径相对于NetBeans项目的顶部:

package my.path.to.this.directory;

我建议在调试器中同时运行服务器和客户端,并逐步执行以查看在每个时间点会发生什么。 这将帮助您在每个点上确认期望值。 Eclipse和其他Java IDE具有相当不错的(且易于使用)调试器。

至于您的代码:

  1. 我会为每个循环迭代执行一次line.trim(),而不是trim()反复重复和不必要地创建额外的对象。
  2. 确保客户端和服务器在每次请求/响应后都冲洗()Socket的OutputStream。 如果未刷新套接字的OutputStream,则连接另一端的InputStream可能会阻塞等待输入,而OutputStream阻塞等待填充其缓冲区。
  3. 客户端中的代码是什么样的? 您确定它发送的是null或“。” 关闭连接? 在检查“。”之前是否需要trim()?
  4. 正如其他人提到的那样,您的代码不遵循典型的Java编码约定。 我建议您阅读Java的已发布代码约定以加快速度。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM