Как получить объем данных в DataInputStreaam? - Джава

В настоящее время я пишу серверную часть многопользовательской игры, над которой я работаю. И мне нужно знать, сколько данных поступает в серверный сокет, чтобы я мог их все циклически просмотреть. Например, если я дважды выполняю writeUTF (), как я буду перебирать их, не получая исключения? Сначала я попытался поймать попытку с EOFException. Но вы, кажется, не можете их поймать. Итак, как мне получить объем данных, получаемых в DataInputStream? Спасибо! -Трент

P.S. Если вам нужен код, дайте мне знать, и я вставлю его сюда!


person Whirvis    schedule 23.02.2015    source источник
comment
Короткий ответ: нельзя. Самое простое решение - создать отдельный поток для каждого клиента.   -  person user253751    schedule 23.02.2015
comment
@immibis Хорошо, спасибо за информацию! Мне просто нужно найти другой способ отправить его :)   -  person Whirvis    schedule 23.02.2015


Ответы (1)


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

  • Включите в свой протокол связи поле длины или код команды, указывающий длину.

  • Используйте асинхронное чтение и запись или используйте поток, предназначенный для взаимодействия.

  • Прежде чем переходить к клавиатуре и коду, подумайте об архитектуре своего приложения, его компонентах, их функциях и их взаимосвязи.

person Tarik    schedule 23.02.2015
comment
Спасибо за информацию! Я нашел другой способ получить это, я узнал о методе available () и использовал его. Я прокрутил его таким образом и поместил все данные в ArrayList, а затем циклически перебрал данные, используя цикл for. - person Whirvis; 23.02.2015
comment
JVM @ SuperstarGamer-Trent могут делать available () всегда возвращать 0. Некоторые люди сказали бы, что available () - это ошибка дизайна, которой, вероятно, не было бы, если бы потоки были изобретены сегодня. - person user253751; 23.02.2015
comment
@immibis Да, я знаю, что обычно я бы не стал им пользоваться. Но поскольку единственные данные, которые когда-либо отправляются через сокеты, - это UTF, я буду использовать его. В противном случае я бы не стал. Если вам интересно, почему я отправляю только строки, это потому, что у меня есть созданная мной библиотека, в которой я могу сделать что-то похожее на ByteBuffer, за исключением String, а затем обратно. И да, я могу положить туда длинные, шорты и т. Д. Если вы хотите, я могу отправить вам ссылку на банку, чтобы вы могли попробовать! - person Whirvis; 23.02.2015
comment
Используя доступный метод, вам придется постоянно опрашивать сокет, а не управлять событиями. хотя он должен работать. - person Tarik; 23.02.2015
comment
@ SuperstarGamer-Trent Я не понимаю, как тот факт, что вы отправляете только строки, имеет какое-либо отношение к тому факту, что вы проводите опрос с помощью available (). - person user253751; 23.02.2015
comment
@immibis Нет другого типа данных, кроме UTF (строк), поэтому безопасно использовать available () с readUTF () для получения всех данных, в противном случае я не буду его использовать. - person Whirvis; 23.02.2015
comment
@ SuperstarGamer-Trent, почему это безопасно? Дело не в том, что он может возвращать слишком мало - дело в том, что он всегда может возвращать 0. - person user253751; 23.02.2015
comment
@immibis Хм, я этого не знал. Я поставлю галочку в программе, чтобы справиться с этим, если это произойдет. Как я уже сказал, обычно это небезопасно. Но поскольку я обрабатываю только один тип данных, я могу использовать его для определения количества отправленных данных. В противном случае, если бы я отправлял такие вещи, как строки, короткие, длинные и т. Д., Я бы не использовал это. - person Whirvis; 23.02.2015
comment
@ SuperstarGamer-Trent, для чего вы будете использовать available (), если вас устраивает, что он всегда возвращает 0? - person user253751; 23.02.2015
comment
@immibis Я нет. Пока в моем тестировании он не возвратил 0. Я сказал, что собираюсь добавить обработчик для этого, если это произойдет, вы знаете, как это вызвать, чтобы я мог продолжить и создать хороший способ справиться с этим в сервер? - person Whirvis; 23.02.2015
comment
@ SuperstarGamer-Trent Если он работает на вашей версии Java, хорошо ... но он может работать не на всех. - person user253751; 23.02.2015
comment
@immibis Хорошо, спасибо за предупреждение! Моя версия Java - Java 8, и она предназначена для частного использования, так что это не должно быть проблемой. Кроме того, вы знаете, что такое 0 Вещь, о которой вы говорили? Я хотел бы знать, чтобы я мог добавить обработчик :) - person Whirvis; 23.02.2015
comment
@ SuperstarGamer-Trent Любое решение, которое работает, если available () всегда возвращает 0, кстати, не будет использовать available () вообще. - person user253751; 23.02.2015
comment
@immibis Хорошо. Спасибо за информацию! Я думаю, что знаю хороший способ отправить все данные, так как мои данные в строковом формате, отправить все в одной строке, а затем поставить - посредине из двух? Я не знаю, мне нужно найти способ сделать это. Но что-то подобное, но пока я просто буду использовать available (). Спасибо, что сообщили мне, что available () ненадежен, поэтому я не делаю ошибок в коде, вызывающих сбои в работе моих серверов: D - person Whirvis; 23.02.2015
comment
@ SuperstarGamer-Trent Я думаю, мне следует уточнить, что было раньше - available () не гарантированно надежен, но это не значит, что он не на самом деле надежен - в любом случае он может быть надежным для некоторых, большинства или всех систем. Но это не гарантируется, поэтому для 100% надежного кода (который работает в любой системе Java, включая те, которые еще не были созданы), вы не можете предполагать, что он работает. - person user253751; 23.02.2015
comment
@immibis А, хорошо. Но я придумаю другой способ, который на 100% надежен! Большое спасибо за информацию! Хорошего дня! -Трент - person Whirvis; 23.02.2015
comment
@immibis UPDATE, я понял, что могу попытаться поймать EOFException, которое срабатывает при чтении большей части любого типа данных. Будет ли добавление данных до тех пор, пока это не произойдет (UTF), а затем разорвать цикл и игнорировать его? Поскольку я знаю, когда это произойдет и почему? - person Whirvis; 23.02.2015
comment
@ SuperstarGamer-Trent вы получите исключение EOFException, только если поток закрыт, но если вы все равно закрываете поток, тогда да. (Исключение EOFException гарантировано) - person user253751; 23.02.2015
comment
@immibis Хорошо, я воспользуюсь этим. Таким образом, у меня нет шансов получить 0. И мне не нужно беспокоиться о попытках получить вещи, которые не являются строками (например, я отправляю строку и короткую строку, но сервер пытается прочитать две струны) - person Whirvis; 24.02.2015