2012-05-30 1 views
3

Я пишу игру Battleships в Java для управляемых событиями программ на моих занятиях. Игра должна быть сетевой игрой, и я собираюсь сделать клиент и сервер в одном приложении.Java - создание отдельной темы для отправки объектов через Интернет

Это изображение, представляющее собой структуру моего приложения: class diagram http://dl.dropbox.com/u/41993645/mvc.jpeg

Чтобы добраться до точки - я хочу написать класс сервера, который будет работать, как отдельный поток и несет ответственность за удаленным видом - связи контроллера. Таким образом, класс сервера будет нести ответственность за:

  • Чтение объектов из сокета в бесконечном цикле и если приходит, положить их в BlockingQueue для контроллера.
  • Предоставление метода, такого как 'sendActionEventToView()', который позволит Контроллеру передавать объект другим способом - от контроллера до удаленного представления.

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

/** Main Server method - responsible for reading objects 
* and putting them in the queue if any arrived */ 
public void run() { 
    GameEvent event; 
    while(true) { 
    try { 
     event = (GameEvent)objectStream.readObject(); 
     if(event != null) eventQueue.put(event); 
    } catch(ClassNotFoundException e) { 
     e.printStackTrace(); 
    } catch(IOException e1) { 
     e1.printStackTrace(); 
    } catch(InterruptedException e2) { 
     e2.printStackTrace(); 
    } 
    } 
} 

Я думаю, что нить висит на «readingObject()» - как я могу заставить его дать процессорное время на другой резьбы, если нет каких-либо объектов в поток?

Остальной сервера: https://github.com/mc-suchecki/Battleships/blob/master/controller/Server.java Остальные приложения: https://github.com/mc-suchecki/Battleships

Большое спасибо заранее, если что-то неясно, пожалуйста, комментарии. И извините за мой английский.

+0

Вам нужно будет опубликовать несколько примеров сжатого кода, прежде чем большинство ответит. Я предлагаю вам добавить дополнительную отладку 'println' или использовать отладчик, чтобы выяснить вашу проблему. – Gray

+0

Спасибо, я отправил проблемный код. Я пробовал отлаживать, но мои знания позволили мне просто найти проблему, но, к сожалению, не решить ее. –

+2

Вы начинаете один поток на одного клиента или читаете с одного клиентского соединения за раз? – Gray

ответ

0

Я просто нашел эту проблему - это в конструкторе:

/** Server class constructor */ 
public Server(BlockingQueue<GameEvent> queue) { 
    eventQueue = queue; 
    try { 
    serverSocket = new ServerSocket(Constants.PORT_NUMBER); 
    socket = serverSocket.accept(); 
    inputStream = socket.getInputStream(); 
    objectStream = new ObjectInputStream(inputStream); 
    } catch(IOException e) { 
    e.printStackTrace(); 
    } 
    Thread thread = new Thread(this); 
    thread.start(); 
} 

Линия с socket = serverSocket.accept() повешено приложением до создания отдельного потока. Я не знаю почему, но я искал проблему в методе run(), и это было неправильно.

+0

Да; принимать блоки до соединения. – KarlP

0

Нормальные потоки java: блокировка. это означает, что вы обычно хотите использовать 2 потока для подключения сокетов (предполагая двунаправленную связь). один поток посвящен каждому потоку (ввод/вывод) для каждый разъем для подключения.

+0

Хорошо, я знаю - я только пытался сделать одностороннюю связь уже , Если быть точным - на сервере будет только один сокет, а один сокет в клиенте - приложение должно быть p2p. –

0

Если вы действительно используете несколько потоков, то когда один поток заблокирован, другие потоки будут запущены. Нет необходимости «заставлять» процессор выделять время другим потокам.

Глядя на ваш код на ваш взгляд вызывает метод запуска Контролера непосредственно вместо того, чтобы отдать его другой поток бежать: https://github.com/mc-suchecki/Battleships/blob/75e6cf69d081c05845f4171bf42ce096ed5247a7/view/View.java#L48 которые могли бы привести к Controller's коду, который будет работать в том же потоке, что называется createServer.

В вашей сути вы уже отправляете свой Controller в новый поток в конструкторе Controller's (https://gist.github.com/2835863#L46). Я предполагаю, что вы можете просто удалить вызов на «controller.run()» в своем представлении.

+0

Спасибо, это правильно, что controller.run() не нужно, но проблема все еще существует. –

0

Если ваш код public void run(); запускается с использованием метода запуска Thread, readObject может блокировать только этот поток.

+0

Я думал то же самое, когда писал код сервера, но по какой-то причине приложение зависает. –

0

Убедитесь, что у вашего run метод имеет нить все для себя. Я подозреваю, что вы делаете много с одной нитью; все ваши потоки - это действительно один поток, и все они ждут в сокете. И когда они (единственные) читают что-то, они просто возвращаются и снова ждут розетки.

Используйте свою IDE, чтобы убедиться, что у вас есть все необходимые темы. Используйте свой отладчик. Приостанавливайте программу, когда она зависает и проверяет все потоки. Убедитесь, что у вас есть как минимум два. (Если вы этого не сделаете, это проблема.) Один нить должен быть висящим на разъеме прочитанным. Проверьте, где другие, если они существуют, висят и исправляют код, чтобы они этого не делали.

Смежные вопросы