Как закрыть поток в Java? - PullRequest
       11

Как закрыть поток в Java?

1 голос
/ 20 февраля 2010

Я очень новичок в 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-политику, но он все равно не получает клиента.Я также должен отметить, что я собираюсь сделать так, чтобы это был многопользовательский сервер, поэтому мне нужно держать сокет открытым и просто закрыть один поток.

Ответы [ 4 ]

3 голосов
/ 20 февраля 2010

На первый взгляд, ваш метод run() выглядит так, как будто он должен завершиться нормально.Я подозреваю, что ваш цикл:

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

Поскольку maxConnections инициализируется в 0 и никогда не увеличивается, цикл, кажется, работает бесконечно и создает много потоков - возможно, столько, сколько сокет может принять слушателей.И затем он вырывается из цикла с IOException.Это то, что на самом деле происходит?

Обновление: , видимо, нет ... пока нет идей.

0 голосов
/ 20 февраля 2010

Я бы посоветовал запустить сервер и клиент в отладчике и пошагово выполнить выполнение, чтобы увидеть, что происходит в каждый момент времени.Это поможет вам подтвердить ожидаемые значения в каждой точке.Eclipse и другие Java IDE имеют довольно хорошие (и простые в использовании) отладчики.

Что касается вашего кода:

  1. Я бы сделал line.trim () один раз для каждогоитерация цикла, а не trim (), повторяющаяся и без необходимости создающая дополнительные объекты.
  2. Убедитесь, что клиент и сервер сбрасывают () выходной поток Socket после каждого запроса / ответа.Если OutputStream сокета не был очищен, InputStream на другом конце соединения может блокировать ожидание ввода, в то время как OutputStream блокирует ожидание для заполнения его буфера.
  3. Как выглядит код в клиенте?Вы уверены, что он отправляет ноль или "."закрыть соединение?Вам нужно подрезать () перед проверкой на наличие "."
  4. Как уже упоминали другие, ваш код не соответствует типичным соглашениям Java-кодирования.Я бы посоветовал ускориться, прочитав опубликованные соглашения для Java .
0 голосов
/ 20 февраля 2010

Поток умрет после того, как вы вернетесь из doComms.run (). Пожалуйста, пишите заглавными буквами имена классов в Java: это должен быть DoComms, просто для того, чтобы другим программистам на Java было проще следовать коду.

Чтобы закрыть соединение, ваш звонок на server.close() должен сделать это. Чтобы убедиться, что вывод отправляется полностью первым, вы должны позвонить close() или flush() на PrintStream, прежде чем позвонить Socket.close().

Какой вклад вы отправляете? Похоже, если вы только один раз отправите <policy-file-request/> с клиента, вы получите файл только один раз.

Не уверен насчет NetBeans, но жалуется ли на то, что у вас нет package, указанного в верхней части файла .java? Попробуйте добавить следующее объявление пакета, указав путь относительно вершины проекта NetBeans:

package my.path.to.this.directory;
0 голосов
/ 20 февраля 2010

Ваш код имеет смысл. Каков ваш вклад? Если у вас есть 10 строк с надписью «», то он действительно напечатает файл 10 раз. А как насчет всех остальных, если у вас есть пункты? В каждом из них вы печатаете что-то + EOF, но наверняка вы просто хотите напечатать один ответ на запрос. Также ваша переменная «input» не используется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...