| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Сети > Несколько send и recv |
| Автор: Alexey91 11.5.2012, 17:35 |
| Здравствуйте! Выполняю следующую последовательность команд send (user .... send (pass ... send (stat .... recv Когда вывожу буфер от recv выводится всякая абракадабра. Я ожидал увидеть, что мне прислал сервер от последнего send'a Не понимаю почему так происходит. И тогда я правильно понимаю, что необходимо выгружать данные в буфер после каждого send, т.е. send (user .... recv send (pass ... recv send (stat .... recv ? |
| Автор: boostcoder 11.5.2012, 18:12 |
| сокет блокирующий? вообще, покажи код отправки user/pass/stat |
| Автор: feodorv 11.5.2012, 19:43 |
Вообще-то должно выводится то, что прислал сервер в ответ на все три send'а (аккумулированные данные). Должно быть от всех трёх send'ов (присланные сервером данные никто не сбрасывает) В общем случае такой необходимости нет. Но в Вашем лучше всё же дождаться ответа (после каждого send) и проверить на ошибку (а вдруг пароль не подошёл?). +1 А ещё код чтения и вывода того, что получено по recv. |
| Автор: Alexey91 12.5.2012, 07:01 | ||||||||||
| Вот код. Выводится только приветствие яндекса. А еще хотелось бы строки "password please" и "+ОК количество_писем суммарный_размер_писем"
Что выводит telnet:
Что выводит прога:
Однако если после 3-х send вызывать 3 раза recv, то получим, что я хочу:
По-хорошему для вывода всех 3-х send размера буфера msg хватает (199 символов) |
| Автор: Alexey91 12.5.2012, 14:48 | ||
Не понял, что ты имеешь ввиду!!! Еще два моих наблюдения: 1. Похоже еще все это зависит от веб-сервера. Например, на яндексе при вызове команды retr, и последующем вызове recv передается: + ОК N octets (или ошибка) Сообщение А на mail.ru нужно два раза вызывать recv после retr. Сначала вернется + OK N octets, а второй recv уже возвращает сообщение Как раз эта ситуация очень меня напрягла, потому что я не понимал почему у меня прога висла. Т.к. у меня стояла два recv, то при работе с яндексом, один recv остался "свободным" и ожидал пока от сервера придут пакеты. Похоже нужно использовать неблокирующие сокеты?? 2. И еще текст сообщение в теле сообщения у яндекса располагается после строки X-Yandex А у mail.ru после X-Mras Почитал RFC 2047, стало понятнее как извлекать заголовки. Но получается так, что нельзя однозначно определить извлечение заголовков для всех серверов, хоть и название заголовков у всех одинаковое. Мне интересно как почтовые программы с этим все разбираются? Они же умеют работать со всеми серверами. Им только адрес хоста передай, и свой логин и пароль, а они все настроят. |
| Автор: feodorv 12.5.2012, 16:59 | ||
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 12.5.2012, 17:21 | ||||
| feodorv, спасибо, все очень подробно написано, теперь я понял ;) По поводу заголовков. Есть кусок сообщения от mail.ru
А вот от yandex'a
У других серверов также свои представления. Заголовки да, они определены стандарты, присутствуют у всех сообщений. Вот как здесь однозначно вырезать нужный текст? Я имею ввиду типа string.substr(begin_pos,length) |
| Автор: feodorv 12.5.2012, 18:47 |
Для mail.ru Вы не привели предшествующих заголовков сообщения, начиная с "From ...". А ведь там задан boundary. А для Яндекса не задан. То есть одним телом сообщения обойтись не удастся. Нужны заголовки сообщения. И уже исходя из них решать, как обрабатывать тело сообщения... Ничего там сложного нет... |