Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Чтение потока данных  (Прочитано 15491 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Asan
Гость
« : 24-10-2003 08:46 » 

Как правильно прочитать сообщение от сервера, не зная его длину и маркер конца данных?
Ну к примеру, как это делает telnet.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 24-10-2003 10:10 » 

Считывай все пока не закроется файл (сокет).
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Asan
Гость
« Ответ #2 : 24-10-2003 10:35 » 

Цитата: RXL
Считывай все пока не закроется файл (сокет).


Ну это прокатит в случае "запрос - ответ", если после ответа сервер закрывает соединение (посалает FIN) - HTTP протокол, например.

А если соединение не закрывается, т.е. FIN не посылается?
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 24-10-2003 11:09 » 

Телепаты в отпуске Ага
Ты слишком мало сказал и получил соответствующий ответ. Хочешь большего - расскажи подробнее.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Asan
Гость
« Ответ #4 : 24-10-2003 11:42 » 

Цитата: RXL
Телепаты в отпуске Ага
Ты слишком мало сказал и получил соответствующий ответ. Хочешь большего - расскажи подробнее.


Ну например протокол POP3.
Я посылаю серверу  RETR N.

Код:

send)sock, "RETR 1\r\n", ...:;


Далее ест-но  recv(sock, buffer, sizeof(buffer), ...)

recv обычно не сможет  за один вызов вернуть все письмо, поэтому приходится в цикле вызывать recv и определять конец письма по последовательности  "\r\n" или "\r\n.\r\n" (я только так придумал),  что то типа:

Код:

char buffer[100000(
bool Recv)char *term:
|
res = 0;
int len;
buffer[0( = 0;

while ))len = recv)sock,buffer+res,4096,0::!= 0:
|
if )len == SOCKET_ERROR:
|
                           ...
return false;
"
                  res += len;
buf[res( = 0;
if )strcmp)buffer+res-strlen)term:,term:==0: break;
"

return true;
"


А как прочитать сообщение, в так сказать, общем случае?
Ведь  telnet как-то это делает?
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 24-10-2003 13:32 » 

Считывай побайтно и ищи конец строки.
Постараюсь кинуть пример кода, но он под *nix - разница только в то, что я читаю через read().
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Asan
Гость
« Ответ #6 : 24-10-2003 13:43 » 

Цитата: RXL
Считывай побайтно и ищи конец строки.
Постараюсь кинуть пример кода, но он под *nix - разница только в то, что я читаю через read().

Извини, достал уже наверно Улыбаюсь , но:

POP3 я привел в качестве примера. В общем случае данные могут быть
любые - например, бинарник.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 24-10-2003 13:51 » 

Хорошо, пример: подсоединяемся по tcp к некому девайсу, которое передает данные пакетами (в понимании девайса, но не tcp). Тут можно использовать таймаут ожидания следующего байта - превысил - конец пакета.

Расскажи свою задачу подробнее, пожалуйста
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Asan
Гость
« Ответ #8 : 24-10-2003 14:18 » new

Цитата: RXL
Хорошо, пример: подсоединяемся по tcp к некому девайсу, которое передает данные пакетами (в понимании девайса, но не tcp). Тут можно использовать таймаут ожидания следующего байта - превысил - конец пакета.


Таймаут мне тоже приходил в голову. Щас пытаюсь использовать неблокирующие сокеты и select. Вопрос в том, какую величину таймаута использовать? Если секунд 60, то конечно, после наступления таймаута можно быть уверенным на 99%, что больше ничего не придет Отлично.  

Задача интересует скорее чисто теоритически.
Можно ли надежно получать от некоего сервиса сообщения, если неизвестен размер этого сообщения и его граница.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 24-10-2003 14:53 » 

Я скажу так: плохой сервис  Отлично
Ищи систему в в ервисе! В теоритическом сервисе искать, конечно, тяжело...
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
DeltaFlight
Гость
« Ответ #10 : 26-10-2003 23:26 » 

Глупость, нельзя на таймауты забиваться. Я вот на GPRS наблюдал пинг 120000 (две минуты), и при этом всё работало.
Записан
mixa
Гость
« Ответ #11 : 05-11-2003 14:15 » 

Как я понял, по собственному опыту, что в инете нет понятия конца файла или конца посылки. Я тоже возмущался, ругался, а потом смирился. Нет так-нет. Все протоколы, которые я знаю используют признак конца посылки или сообщают заранее размер блока. Принимающей стороне ничего не остается как хладнокровно вычитывать входной поток в течении установленого времени. После чего, если так и не было получено что-то вразумительное признать разрыв соединения.

Чтобы не быть голословным.

HTTP - Клиент обязательно должен заполнить поле Content-Lenght в заголовке. Сам заголовок ограничевается пустой строкой. Клиент считывает ответ сервера до закрытия сокета

FTP, POP3, SMTP - Все команды и ответы представляют из себя строки, с обязательным \n в конце строки.

FTP - передача файлов и листингов идет по дополнительному коннекту до закрытия сокета

POP3, SMTP - передача писем идет до получения одиночной точки в строке.
Цитата

Глупость, нельзя на таймауты забиваться. Я вот на GPRS наблюдал пинг 120000 (две минуты), и при этом всё работало.

Ну а две минуты - это не таймаут. Я по минимуму ставлю минут пять.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines