簡體   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