2010-11-29 3 views
0

Все, что я хочу сделать, это начать поток, чтобы прослушивать связь на определенном порту.Простая проблема с потоком

Я начинаю это с кнопки «ok» на jDialog. Когда щелкнули «ok», jDialog должен скрыть себя (HostClientDialog.setVisible (false),), который работает, когда строка начала потока отсутствует.

try { 

      HostClientDialog.setVisible(false); 

      // start a thread that listens for incoming messages 
      new gameCycle().start(); 

} catch (Exception e) { } 

новый товарCycle(). Start(); линия звонит следующий код:

public class gameCycle extends Thread { 

    //public gameCycle(){ 
     // super(); 
    //} 

    @Override 
    public void run() { 

     try { 

      ServerSocket connection = new ServerSocket(4242); 

      // Wait for connection 
      Socket s = connection.accept(); 

      // Socket input 
      BufferedReader in = new BufferedReader(new 
        InputStreamReader(s.getInputStream())); 

      // for receiving moves 
      while (true) { 

       String message = ""; 

       message = in.readLine(); 

       if (message != null && !message.equals("")) { 
        // do something with message 
       } 

       sleep(100); 

      } // end while 

     } catch (Exception e) { } 

    } // end run 
} // end class 

я понял, приведенный выше код будет выполняться цикл, пока не будет получено сообщение, а затем что-то делать с сообщением. Но когда вы выполняете этот код, поле jDialog выполняется снова (мгновенно) и повторно запрашивает пользователя, чтобы щелкнуть ok. Он не позволит пользователю пройти окно jDialog, он будет просто постоянно запрашивать их.

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

EDIT (11/29/2010 в 1:30 AM EST)

Кажется, что я не достаточно иметь представление о TCP связи вниз так, как я думал. Моя цель с нитью и последующее время цикла был следующим:

  • На заднем плане программа будет будет ждать каких-либо сообщений, отправленного его пути
  • Если он получил сообщение, что будет обновлять что-то на GUI, а затем вернуться к ожиданию дополнительных сообщений.

Все это время позволяет пользователю постоянно использовать графический интерфейс пользователя.

ответ

1

Я бы сказал, что код, который вы предоставили, выглядит хорошо для меня.

Я бы воспользовался возможностью отменить весь поток вместо того, чтобы зацикливать while (true). Вместо этого используйте boolean и сделайте логическое значение доступным для других потоков. Если вам нужна помощь в этом, вернитесь ко мне.

Я думаю, что проблема заключается в коде, который мы НЕ видим здесь. Меня частично интересуют фрагменты кода, связанные с вызовом .start() в вашем потоке. Что происходит после этого?

веселит

EDIT:

public class Main { 

/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) { 
    final JDialog dia = new JDialog(); 
    JButton btn = new JButton("Foo"); 
    btn.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent ae) { 
      dia.setVisible(false); 
      Runnable t = new Runnable() { 
       public void run() { 
        System.out.println("foo"); 
       } 
      }; 
      t.run(); 
     } 
    }); 
    dia.getContentPane().add(btn); 
    dia.setSize(500, 400); 
    dia.setVisible(true); 
} 
} 

Это отлично работает для меня - извините, но я не могу воспроизвести ошибку, как вы заявили в комментариях. Рассмотрите возможность получения большего количества кода, пожалуйста :)

РЕДАКТИРОВАТЬ # 2: Не устанавливайте какие-либо переменные из вашей нити напрямую. Вместо этого используйте шаблон наблюдателя-слушателя. Когда есть новое сообщение, входящее, попробуйте поток thread вместо свойстваChangeEvent. http://download.oracle.com/javase/1.4.2/docs/api/java/beans/PropertyChangeListener.html

Возможно, вам стоит попробовать что-то более тривиальное. Сначала сделайте быстрый и простой чат. http://www.ashishmyles.com/tutorials/tcpchat/index.html

Когда у вас это будет, подумайте о своем проекте. Может быть, чтение в многопоточном режиме с помощью swing могло бы помочь? http://java.sun.com/developer/technicalArticles/Threads/swing/

1

Выглядит хорошо, но я подозреваю, что этот пустой блок блокировки. Или, возможно, этот метод снова вызывается?

Также, если сообщение == null, вы должны выйти из цикла считывания и закрыть сокет, а сон бессмыслен: readline() будет блокировать, если нет данных. И инициализация «сообщения» также бессмысленно, когда вы собираетесь назначить его в самой следующей строке.

+0

Отмечено. Так что я должен помещать объявления Socket и BufferedReader в цикл while так, чтобы их переделывали каждый раз? – Ryan 2010-11-29 05:36:37

+0

Конечно нет. Не знаю, как вы это поняли из того, что я сказал. Вы не можете сделать это в случае сокета, и если вы сделаете это с помощью BufferedReader, вы потеряете данные. – EJP 2010-11-29 05:51:03

+0

Я не знал, как соединение останется неповрежденным, если я закрываю сокет в нижней части цикла while. Если я закрою сокет в нижней части цикла while, линия in.readLine() снова откроет соединение? – Ryan 2010-11-29 05:57:16

1

я понял, приведенный выше код будет выполняться цикл, пока сообщение не получено

Не совсем. Эта линия:

Socket s = connection.accept(); 

блокирует выполнение резьбы до тех пор, пока не будет установлено соединение. Вы уверены, что это происходит? Возможно, ваша программа просто сидит там, ожидая подключения, но никто не делает (все равно успешно).

Возможно, опубликуйте дополнительную информацию, например, как выглядит класс, запрашивающий соединение.