URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 3770
[ Назад ]

Исходное сообщение
"Простой pop3 клиент,не приходят данные"

Отправлено Guest , 27-Дек-04 00:41 
Нужен простой pop3 клиент,скачивающий почту.
Разобравшись с командами pop3,без труда скачиваю почту telnet'ом:
+OK e-post01.e-se.ru POP3 e-Style Post 2.3.30 ready
USER smtp-tester
+OK User accepted
PASS xxx
+OK Authenticated
LIST
+OK List follows
1 3242
Но почему-то моя прога виснет,после того как я посылаю USER smtp-tester,т.е не приходит строка +OK User accepted.Вот код:

con=connect(sock,&addr,sizeof(addr));
        if(con==-1) { perror("Cannot connect\n"); exit(1); }
printf("Connected....\n");

recv(sock,buf1,512,0); //строка +OK e-post01.e-se.ru POP приходит и печатается

printf("%s\n",buf1);

printf("Sending username...\n");
send(sock,user,sizeof(user),0);

printf("Receiving string...\n");
recv(sock,buf2,512,0); // А вот здесь прога и висит!!!!!
printf("%s\n",buf2);

В чем может быть загвоздка?


Содержание

Сообщения в этом обсуждении
"Простой pop3 клиент,не приходят данные"
Отправлено Xela , 27-Дек-04 10:53 
Как формируете строку, которая в переменной user?

"Простой pop3 клиент,не приходят данные"
Отправлено Guest , 27-Дек-04 11:23 
>Как формируете строку, которая в переменной user?
Xela,огромное вам спасибо,прочитав ваш пост я понял что не добавил '\n' в конец строки!!!С этим все работает.Я так однажды споткнулся,писав http запрос - там тоже надо добавлять \n\n в конец запроса)

"Простой pop3 клиент,не приходят данные"
Отправлено Guest , 27-Дек-04 12:31 
Рано я обрадовался.....
Почему-то на пароль сервер реагирует ошибкой:
...
char pass[]="PASS xxx\n"
...
send(sock,pass,sizeof(pass),0);
recv(sock,buf1,512,0);

и на это он пишет

-ERR Unknown command


"Простой pop3 клиент,не приходят данные"
Отправлено Alexander S. Salieff , 27-Дек-04 19:15 
>Рано я обрадовался.....
>Почему-то на пароль сервер реагирует ошибкой:
>...
>char pass[]="PASS xxx\n"
>...
>send(sock,pass,sizeof(pass),0);
>recv(sock,buf1,512,0);
>
> и на это он пишет
>
>-ERR Unknown command

Не исключено что сервер слишком рьяно блюдет терминальные нотации. Общепринятый перевод строки CR+LF, попробуй char pass[]="PASS xxx\r\n"


"Простой pop3 клиент,не приходят данные"
Отправлено Guest , 27-Дек-04 21:12 

>Не исключено что сервер слишком рьяно блюдет терминальные нотации. Общепринятый перевод строки
>CR+LF, попробуй char pass[]="PASS xxx\r\n"

Да, я попробовал.Не помогло.Ситуация такая - сервак(тестировал на разных) принимает первую команду нормально(NOOP,USER ит.д) а любую последующую как -ERR Unknown command.
Где-то я спотыкаюсь.Возможно со второй командой посылаются остатки первой.Даже если я подряд два нопа шлю,то первый - +OK,второй - -ERR

Вот код.
#include

char buf1[512];

int main() {

char user[]="USER smtp-tester\r\n";
char pass1[]="PASS xx\r\n";
char noop[]="NOOP\r\n";

socket,connect.....
recv(sock,buf1,100,0);//получаем +OK e-post01.e-se.ru POP3 e-Style Post 2.3.30 ready

//и далее
send(sock,user,sizeof(user),0);
memset(&buf1,'\0',sizeof(buf1));
recv(sock,buf1,100,0);
printf("%s \n",buf1); //Получаем +OK User accepted

//а дальше
send(sock,pass1,sizeof(pass1),0);
memset(&buf1,'\0',sizeof(buf1));
recv(sock,buf1,100,0);
printf("%s \n",buf1); //Получаем -ERR Unknown command

В чем может быть дело?Киньте плз ссылку на pop3 исходник,может там есть что



"Простой pop3 клиент,не приходят данные"
Отправлено Soldier , 28-Дек-04 12:05 
>
>>Не исключено что сервер слишком рьяно блюдет терминальные нотации. Общепринятый перевод строки
>>CR+LF, попробуй char pass[]="PASS xxx\r\n"
>
>Да, я попробовал.Не помогло.Ситуация такая - сервак(тестировал на разных) принимает первую команду
>нормально(NOOP,USER ит.д) а любую последующую как -ERR Unknown command.
>Где-то я спотыкаюсь.Возможно со второй командой посылаются остатки первой.Даже если я подряд
>два нопа шлю,то первый - +OK,второй - -ERR
>
>Вот код.
>#include
>
>char buf1[512];
>
>int main() {
>
>char user[]="USER smtp-tester\r\n";
>char pass1[]="PASS xx\r\n";
>char noop[]="NOOP\r\n";
>
>socket,connect.....
>recv(sock,buf1,100,0);//получаем +OK e-post01.e-se.ru POP3 e-Style Post 2.3.30 ready
>
>//и далее
>send(sock,user,sizeof(user),0);
>memset(&buf1,'\0',sizeof(buf1));
>recv(sock,buf1,100,0);
>printf("%s \n",buf1); //Получаем +OK User accepted
>
>//а дальше
>send(sock,pass1,sizeof(pass1),0);
>memset(&buf1,'\0',sizeof(buf1));
>recv(sock,buf1,100,0);
>printf("%s \n",buf1); //Получаем -ERR Unknown command
>
>В чем может быть дело?Киньте плз ссылку на pop3 исходник,может там есть
>что


Нули то зачем серверу слать? :)))   В send(sock,user,sizeof(user),0); вместо "sizeof(user)" используйте  "sizeof(user)-1" Тоже касается и  send(sock,pass1,sizeof(pass1),0)


"Простой pop3 клиент,не приходят данные"
Отправлено Alexander S. Salieff , 28-Дек-04 14:33 
>Нули то зачем серверу слать? :)))   В send(sock,user,sizeof(user),0); вместо "sizeof(user)"
>используйте  "sizeof(user)-1" Тоже касается и  send(sock,pass1,sizeof(pass1),0)

И верно чел говорит ;)
Тока тогда уж по красивому strlen(user) и т.д. Я даж внимания по наивности не обратил, что там sizeof'ы вместо strlen'ов стоят ;)


"Простой pop3 клиент,не приходят данные"
Отправлено Guest , 28-Дек-04 15:22 

>Нули то зачем серверу слать? :)))   В send(sock,user,sizeof(user),0); вместо "sizeof(user)"
>используйте  "sizeof(user)-1" Тоже касается и  send(sock,pass1,sizeof(pass1),0)

2Soldier:Спасибо,так работает - т.е либо sizeof(user)-1 либо strlen(user)
Но что мне делать ,когда я посылаю ему LIST,в ответ он мне шлет несколько строк?
Конструкция типа

while(1) {

int h=recv(s,p,512,0);
if(h==0) { break;}
printf("%s \n",p);

}

не работает,т.е прога ждет данных....может пометить сокет как неблокирующий?


"Простой pop3 клиент,не приходят данные"
Отправлено Alexander S. Salieff , 28-Дек-04 15:44 
>
>>Нули то зачем серверу слать? :)))   В send(sock,user,sizeof(user),0); вместо "sizeof(user)"
>>используйте  "sizeof(user)-1" Тоже касается и  send(sock,pass1,sizeof(pass1),0)
>
>2Soldier:Спасибо,так работает - т.е либо sizeof(user)-1 либо strlen(user)
> Но что мне делать ,когда я посылаю ему LIST,в ответ он
>мне шлет несколько строк?
>Конструкция типа
>
>while(1) {
>
>int h=recv(s,p,512,0);
>if(h==0) { break;}
>printf("%s \n",p);
>
>}
>
>не работает,т.е прога ждет данных....может пометить сокет как неблокирующий?


Короче, если не хочется делать poll/select-демультиплексор и писать собственный коллектор строк, то перемапливаем наш сокет на буферизованный файл (внимание, в виндах не прокатит!):
FILE * myfd = fdopen(s, "r+");
Потом шлем туда коммандные строки инструкциями вроде:
fprintf(myfd, "LIST\r\n");
И построчно принимаем ответы:
char tmp_buf[1001]={0};
while(fgets(tmp_buf, 1000, myfd)!=NULL)
{
Чего-то творим со строкой tmp_buf, не забывая что она в конце имеет "\r\n"
}
Теперь опеределяемся с LIST. Во первых, LIST сообщает, сколько она хочет отдать строк, во вторых, заканчивает вывод строкой ".\r\n":
C: LIST
S: +OK 2 messages (320 octets)
S: 1 120
S: 2 200
S: .
Т.е. у нас 2 пути - либо парсим первую строку ответа, выясняя (в данном примере) что у нас именно "2" messages и потом считываем 2 строки и одну (которая ".\r\n") скипаем, либо скипаем первую, а потом читаем до точки.
Первый вариант:
fprintf(myfd, "LIST\r\n");
char tmp_buf[1001]={0};
char msg_count_buf[1001]={0};
fgets(msg_count_buf, 1000, myfd);
int msg_count = parse_list_answer(msg_count_buf);
for (int i=0; i<msg_count; i++)
{
fgets(tmp_buf, 1000, myfd);
Обрабатываем сообщения
}
fgets(tmp_buf, 1000, myfd); //Сбрасываем точку
Второй вариант:
fprintf(myfd, "LIST\r\n");
char tmp_buf[1001]={0};
fgets(tmp_buf, 1000, myfd); //Скипаем служебный ответ
while(fgets(tmp_buf, 1000, myfd)!=NULL)
{
if (strcmp(tmp_buf, ".\r\n") break;
Чего-то творим со строкой tmp_buf, не забывая что она в конце имеет "\r\n"
}

Короче, почитай спецухи по POP3, по работе с потоками ввода-вывода и по работе со строками - сразу полегчает. Хотя по уму нужно не ремапить сокет на файл (это не очень правильное и переносимое решение, хоть и быстрое), а написать свой сетевой демультиплексор и коллектор строк.


"Простой pop3 клиент,не приходят данные"
Отправлено Guest , 28-Дек-04 18:52 
Да,спасибо ,навели на мысль....
Кстати можно в принципе и так сделать - перед каждой посылкой сообщения поставить парсер,и если первые 4 символа будут 'L 'I' 'S' 'T' то прыгать в спец. функцию,обрабатывающую только посылку-принятие LIST запроса,т.е посылаем LIST,в первой принятой строке узнаем кол-во сообщений и затем в зависимости от этого n кол-во раз вызываем recv()
//Ну вообщем почти как вы сказали
И еще вопросик:У меня почему-то не обнуляется буфер:
void sender(int s,char *str,char *p) { //функция посылки сообщений

memset(p,'\0',sizeof(p)); //Здесь обнуляется буфер для приема

send(s,str,strlen(str),0);

int h=recv(s,p,512,0);

printf("%s \n",p);
}
И вызывыаю я соответственно sender(sock,list,buf1);
и вот buf1 не обнуляется...почему?


"Простой pop3 клиент,не приходят данные"
Отправлено gyn61 , 28-Дек-04 19:45 
>memset(p,'\0',sizeof(p)); //Здесь обнуляется буфер для приема
sizeof(p) это размер указателя (4 байта)

"Простой pop3 клиент,не приходят данные"
Отправлено ACCA , 29-Дек-04 02:19 
>Нужен простой pop3 клиент,скачивающий почту.

man fetchmail

Ребята, постарайтесь не писать следующие программы:

1. ac
2. access
3. alias
...
1973. znew
1974. zsoelim
1975. zxpdf

Есть куча более других дел. С серверами вроде POP можно побаловаться с помощью пары nc+chat.


"Простой pop3 клиент,не приходят данные"
Отправлено Guest , 29-Дек-04 14:24 

>man fetchmail
>
Спасибо всем за ответы,дело пошло.Пока без проблемм)
>Ребята, постарайтесь не писать следующие программы:
>
>1. ac
>2. access
>3. alias
>...
>1973. znew
>1974. zsoelim
>1975. zxpdf
>
>Есть куча более других дел. С серверами вроде POP можно побаловаться с
>помощью пары nc+chat.
Это будет лишь часть проги,ее задача будет только скачать письма и удалить их на почтовом ящике,а дальше уже другой модуль будет ими заниматься)