![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| unkis |
|
||||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 802 Регистрация: 8.9.2004 Репутация: нет Всего: 1 |
Собственно сабж.
Просто имею вот такой вот код
Вот в этом кусочке, зависает один поток, тоесть он не выходит из while.
Тоесть иногда бывает так, что r никогда не будет равна -1. Что посоветуете и как исправить эту проблему? -------------------- www.unkis.com |
||||
|
|||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Если сервер не закрывает свой вывод , то, действительно, никогда и не получите -1. На этом основан серверный push, когда соединение не закрывается, и сервер отправляет данные по мере необходимости. Если же размер "страницы" известен и сервер его указывает в хедере респонса ( поле Content-Length ), то -1 (EOF) должен быть. |
|||
|
||||
| unkis |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 802 Регистрация: 8.9.2004 Репутация: нет Всего: 1 |
Ну а если размер "страницы" не известен, то как быть?
-------------------- www.unkis.com |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Если размер серверу заранее не известен, то он может:
1. Или добавить хедер "Connection : close" в респонс, означающий, что концом данных служит закрытие соединения. Это типично для HTTP 1.0 И это не совместимо с keep-alive, т.е. сокетное соединение не может быть повторно использовано для последующих запросов на этот же сервер. 2. Или использовать режим chunked (наиболее вероятно). О чем сервер также должен предупредить клиента, поместив соответствующий хедер в респонс. Это разрешено только в HTTP 1.1, т.е. если клиент прислал запрос в HTTP1.1 и сервер это поддерживает. В этом случае респонс отправляется порциями (chunk) и перед каждым чанком высылается его размер. Конец данных - чанк нулевой длины. Чтобы не программировать вручную распознавание конца данных наверное лучше читать строками, а не посимвольно (не из стрима). Я не имел дела с HttpClient, но, думаю, там есть такая возможность. Это сообщение отредактировал(а) COVD - 15.1.2009, 03:12 |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 3 Всего: 40 |
есть нормальный метод HttpMethod#getResponseBodyAsString();
или я не понял глубины вопроса? Это сообщение отредактировал(а) Platon - 15.1.2009, 15:05 |
|||
|
||||
| unkis |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 802 Регистрация: 8.9.2004 Репутация: нет Всего: 1 |
Есть такой метод, но почему-то apache не рекомендует его использовать
-------------------- www.unkis.com |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 3 Всего: 40 |
Добавлено через 1 минуту
Нуу, есть такой момент, но если сервисы не падлят клиентам, то проблем не будет никогда. Добавлено через 4 минуты и 48 секунд Можете использовать HttpMethod#getResponseBodyAsString(int maxlen) |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Если читать ответ посимвольно, из потока, то надо сначала проверить наличие хедера Transfer-Encoding: chunked ( для HTTP1.1 ). Если он присутствует, то формат для тела ответа такой (
http://developers.sun.com/mobility/midp/questions/chunking/ ) :
В этом примере данные разбиты на два чанка и присутствует чанк нулевой длины в конце, означающий конец данных. Размер первого чанка равен 12, что в hex дает C. Передается размер чанка ( 3 байта ) : 67 ( это 'С' ) , 13 ( это '\r' ) , 10 ( это '\n' ) Потом следуют 12 байт данных ("Some data...") . Размер второго чанка равен 17 , что в hex дает 11. Передается размер чанка ( 4 байта ) : 49 ( это '1' ), 49 ( это '1' ), 13 ( это '\r' ) , 10 ( это '\n' ) Потом следуют 17 байт данных ("Some more data...") . Конец данных - чанк нулевой длины. Это три байта: 48 (это '0') , 13 ( это '\r' ) , 10 ( это '\n' ) Соединение сервером не закрывается. Поэтому, надо полагать, никакого -1 получено не будет. Однако, возможно, есть более простое решение, чем парсить chunked stream. В запросе можно явно указать серверу, что клиент не нуждается в повторном использовании соединения. Для этого служит хедер Connection : close . В этом случае сервер очевидно ( жесткого требования протокол не предьявляет, это следует из здравого смысла ) также предпочтет закрытие соединения после окончания данных. И в этом случае ("If the server chooses to close the connection immediately after sending the response") сервер обязан также указать хедер Connection : close . Таким образом, если посылать запросы с хедером Connection : close , то с большой вероятностью сервер не будет использовать "chunked", а будет отвечать аналогичным хедером и закрывать соединение после отсылки ответа. И -1 будет срабатывать. Или еще один способ - использовать протокол HTTP1.0 . В нем режим "chunked" вообще не предусмотрен и концом данных служит разрыв соединения. Это сообщение отредактировал(а) COVD - 16.1.2009, 06:39 |
|||
|
||||
| unkis |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 802 Регистрация: 8.9.2004 Репутация: нет Всего: 1 |
Спасибо, если я правильно всё понял, то я могу указываю каким протоколом я хочу пользоваться, так?
А если сервер не поддерживает этот протокол? -------------------- www.unkis.com |
|||
|
||||
| COVD |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 26.7.2005 Репутация: 11 Всего: 43 |
Сервер, если стандартный, то поддержит 1.0 . А вот существующие клиенты похоже не позволяют менять версию протокола.
Можно отправку запроса и чтение ответа вручную программировать. Где-то на форуме такие примеры были. Что-то вроде такого:
Вы можете послать на сервер HTTP/1.0 или HTTP/1.1 в первой строке. Но все же лучше в стандартном клиенте попробовать поставить хедер Connection : close. Это сообщение отредактировал(а) COVD - 20.1.2009, 18:38 |
|||
|
||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Работа с сетью | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |