![]() |
Модераторы: feodorv |
![]() ![]() ![]() |
|
Alexey91 |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 195 Регистрация: 18.9.2008 Репутация: нет Всего: нет |
Здравствуйте!
Выполняю следующую последовательность команд send (user .... send (pass ... send (stat .... recv Когда вывожу буфер от recv выводится всякая абракадабра. Я ожидал увидеть, что мне прислал сервер от последнего send'a Не понимаю почему так происходит. И тогда я правильно понимаю, что необходимо выгружать данные в буфер после каждого send, т.е. send (user .... recv send (pass ... recv send (stat .... recv ? |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 13 Всего: 110 |
сокет блокирующий?
вообще, покажи код отправки user/pass/stat |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Вообще-то должно выводится то, что прислал сервер в ответ на все три send'а (аккумулированные данные). Должно быть от всех трёх send'ов (присланные сервером данные никто не сбрасывает) В общем случае такой необходимости нет. Но в Вашем лучше всё же дождаться ответа (после каждого send) и проверить на ошибку (а вдруг пароль не подошёл?). +1 А ещё код чтения и вывода того, что получено по recv. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Alexey91 |
|
||||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 195 Регистрация: 18.9.2008 Репутация: нет Всего: нет |
Вот код.
Выводится только приветствие яндекса. А еще хотелось бы строки "password please" и "+ОК количество_писем суммарный_размер_писем"
Что выводит telnet:
Что выводит прога:
Однако если после 3-х send вызывать 3 раза recv, то получим, что я хочу:
По-хорошему для вывода всех 3-х send размера буфера msg хватает (199 символов) ![]() Это сообщение отредактировал(а) Alexey91 - 12.5.2012, 07:15 |
||||||||||
|
|||||||||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Ну тогда всё понятно ![]() Видимо, первый recv отрабатывает очень быстро, а поп-сервер ещё не успел прислать ответ на имя пользователя и пароль. Поэтому вариант recv-send-recv-send-recv... - самый правильный ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Alexey91 |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 195 Регистрация: 18.9.2008 Репутация: нет Всего: нет |
Не понял, что ты имеешь ввиду!!! Еще два моих наблюдения: 1. Похоже еще все это зависит от веб-сервера. Например, на яндексе при вызове команды retr, и последующем вызове recv передается: + ОК N octets (или ошибка) Сообщение А на mail.ru нужно два раза вызывать recv после retr. Сначала вернется + OK N octets, а второй recv уже возвращает сообщение Как раз эта ситуация очень меня напрягла, потому что я не понимал почему у меня прога висла. Т.к. у меня стояла два recv, то при работе с яндексом, один recv остался "свободным" и ожидал пока от сервера придут пакеты. Похоже нужно использовать неблокирующие сокеты?? 2. И еще текст сообщение в теле сообщения у яндекса располагается после строки X-Yandex А у mail.ru после X-Mras Почитал RFC 2047, стало понятнее как извлекать заголовки. Но получается так, что нельзя однозначно определить извлечение заголовков для всех серверов, хоть и название заголовков у всех одинаковое. Мне интересно как почтовые программы с этим все разбираются? Они же умеют работать со всеми серверами. Им только адрес хоста передай, и свой логин и пароль, а они все настроят. Это сообщение отредактировал(а) Alexey91 - 12.5.2012, 14:51 |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
TCP обеспечивает потоковое сообщение между клиентом и сервером. Поток прерывается в трёх случаях: когда клиент или сервер закрыли соединение, когда клиенту или серверу нечего слать друг другу, и когда клиент или сервер медленно отсылают сообщения. Последний случай - наш. Как работает блокирующий recv? Сначала он смотрит в буфер приёма, присоединённый к сокету, и считывает данные оттуда. Если данных в буфере приёма нет, recv их ждёт. Если данные для чтения в буфере приёма есть (или мы их дождались) и их достаточно для полного заполнения пользовательского буфера, то recv возвращает управление пользователю. А вот если данных мало (они не заполняют пользовательский буфер целиком), recv ждёт непродолжительное время (таймаут ожидания) новой порции данных и лишь потом возвращает управление. То есть recv не знает, придут ли по сокету ещё данные или нет, а возвращает имеющиеся в наличии. Что получается у нас? Клиент: send( "command1\r\ncommand2\r\n" ) Сервер: send( "Hello\r\n" ); recv( "command1\r\ncommand2\r\n" ); обрабатываем command1; send( "answer1\r\n" ); обрабатываем command2; send( "answer2\r\n" ); recv( ... ); Клиент: recv( "Hello\r\n" ); таймаут ожидания; То есть ответы answer1 и answer2 не успевают прочесться клиентским recv - то ли сеть медленно работает, то ли сервер подтормаживает, но истекает таймаут ожидания, и recv возвращает то, что есть в буфере приёма - "Hello". А ответы даже не пытается прочесть... То есть нужно while( recv() ), но тогда нужно указать точный критерий выхода из while (если не было ошибки). Поэтому-то всё-таки лучше всего пошаговый обмен сообщениями... А то. Если он быстрый, то ответы быстро шлёт. Всё успевает сбуферизироваться в один recv...
Почему? Всё стандартизировано, RFC есть. X-заголовки - это заголовки расширения первоначального протокола, но и о них договорились... Поэтому почтовые программы и не теряются при обмене с поп-сервером... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Alexey91 |
|
||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 195 Регистрация: 18.9.2008 Репутация: нет Всего: нет |
feodorv, спасибо, все очень подробно написано, теперь я понял ;)
По поводу заголовков. Есть кусок сообщения от mail.ru
А вот от yandex'a
У других серверов также свои представления. Заголовки да, они определены стандарты, присутствуют у всех сообщений. Вот как здесь однозначно вырезать нужный текст? Я имею ввиду типа string.substr(begin_pos,length) Это сообщение отредактировал(а) Alexey91 - 12.5.2012, 17:29 |
||||
|
|||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 10 Всего: 45 |
Для mail.ru Вы не привели предшествующих заголовков сообщения, начиная с "From ...". А ведь там задан boundary. А для Яндекса не задан. То есть одним телом сообщения обойтись не удастся. Нужны заголовки сообщения. И уже исходя из них решать, как обрабатывать тело сообщения... Ничего там сложного нет... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Сети | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |