Russian Qt Forum

Qt => Работа с сетью => Тема начата: serg_hd от Май 21, 2010, 12:57



Название: POP3
Отправлено: serg_hd от Май 21, 2010, 12:57
Вопрос в следующем: как узнать сколько максимум октет выдаётся этим протоколом за один пакет? Например статистика показала что всего в письме 109168 октет. Мне их все нужно считать. Использую для этого (в отдельном потоке):
Код
C++ (Qt)
QString str;
...
if (this->socket->waitForReadyRead(30000))
{
str.append(this->socket->readAll());
}
 
Проблема в том, что нужно знать сколько раз это условие вызывать, чтобы прочитать всё письмо каким бы оно большим не было. Пробовал 512, 1024, 2048 - не то.
Или вообще может быть есть какой-то более рациональный способ как получить содержимое большого (от 32 строк) письма?


Название: Re: POP3
Отправлено: garryHotDog от Май 21, 2010, 13:37
попробуй посмотреть исходный код открытых клиентов, как там делается это !


Название: Re: POP3
Отправлено: crossly от Май 21, 2010, 14:09
для это есть сигнал readyRead() сделай слот и читай хоть до посиниения.... а вообще тема pop3 уже понималась.... поищи по форуму


Название: Re: POP3
Отправлено: serg_hd от Май 21, 2010, 14:23
для это есть сигнал readyRead() сделай слот и читай хоть до посиниения.... а вообще тема pop3 уже понималась.... поищи по форуму
Какбэ в том и проблема, что читать надо не до посинения, а до конца письма. И надо точно знать когда он будет. Такая проблема тут не подымалась.


Название: Re: POP3
Отправлено: serg_hd от Май 21, 2010, 14:39
Частично решено тем, что от общего кол-ва октет при каждой итерации вычитается кол-во возвращённое каждым ответом:
Код
C++ (Qt)
...
     this->socket->write("RETR " + QString::number(this->listsCount).toLatin1() + "\r\n");
 
     //read last email
     if (this->socket->waitForReadyRead(30000))
     {
      QString strAllOctets = this->socket->readAll().trimmed();
      int intAllOctets = strAllOctets.split(" ").at(1).toInt();
      qDebug() << "all octets:" << intAllOctets;
      QString strReply,
              strAppend;
      forever
      {
       if (this->socket->waitForReadyRead(5000))
       {
        strAppend = this->socket->readAll();
        strReply.append(strAppend); //добавление полученного фрагмента к сумме предыдущих
        intAllOctets -= strAppend.length();
        if (intAllOctets <= 0) break;
       }
      }
...
 
Когда октет уже не осталось, значит все данные переданы. Но это работает если письмо небольшое (проверял на 44 строках).
А если в нём, например, 5160 строк, то таким образом прочтёт почему-то только 4941 строку.


Название: Re: POP3
Отправлено: crossly от Май 21, 2010, 15:10
дык епть... попроси у сервера сначала размер письма.... а потом уже само письмо ... и читай сколько тебе надо...


Название: Re: POP3
Отправлено: serg_hd от Май 21, 2010, 15:12
дык епть... попроси у сервера сначала размер письма.... а потом уже само письмо ... и читай сколько тебе надо...
Код
C++ (Qt)
qDebug() << "all octets:" << intAllOctets;
 
Вы на код смотрели?


Название: Re: POP3
Отправлено: crossly от Май 21, 2010, 15:20
ага... слегка бредовый... когда то писал клиента если найду выложу.... а пока на это посмотри http://qt.gitorious.org/qt-labs/messagingframework/blobs/master/src/plugins/messageservices/pop/popclient.cpp


Название: Re: POP3
Отправлено: serg_hd от Май 21, 2010, 15:21
ага... слегка бредовый...
То что бредовый было вычислено сразу, а то, что там читается полный размер письма значит нет? ;D Интересная логика.
И мне не нужны сигналы/слоты, я уже говорил что в отдельном потоке это всё делаю...


Название: Re: POP3
Отправлено: serg_hd от Май 22, 2010, 00:51
Вобщем из-за непонятного соответствия отданный_октет/полученный_байт чтение письма любого размера свелось к:
Код
C++ (Qt)
 socket->write("RETR 3\r\n");
 QString m_messages;
 while(socket->waitForReadyRead(5000))
   m_messages.append(socket->readAll());
 
 qDebug() << m_messages; //show all letter's text
 


Название: Re: POP3
Отправлено: Spicos от Май 28, 2010, 06:28
у меня как-то так
Код:
int POP3::connect_pop3()
{
  if (POP3_State!=NONE_State) return 0;
  count_command=0;
  Pop3Socket->disconnectFromHost();
  POP3_State=CONNECT_State;
  connect(Pop3Socket,SIGNAL(readyRead()),SLOT(socketReadyRead()));
  connect(this,SIGNAL(ReadMailComplete()),SLOT(MailParse()));
  connect(this,SIGNAL(Response_Ready()),SLOT(ParsePOP3Command()));
  connect(this,SIGNAL(Next()),SLOT(time_out()));
  if (type_socket==1) {
        connect(Pop3Socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslErrors(QList<QSslError>)));
        Pop3Socket->connectToHostEncrypted(mail_server,port);
    }
  else {
    Pop3Socket->connectToHost(mail_server,port,QIODevice::ReadWrite);
  }
  return 0;
}


void POP3::socketReadyRead()
{
  if ( !Pop3Socket->canReadLine() ) return;
  QByteArray temp = Pop3Socket->readAll();
  //qDebug()<<temp;
  mail_RAW.append(temp);
  if (POP3_State==RETR_State || POP3_State==TOP_State) {
    if( mail_RAW.endsWith("\r\n.\r\n")) {
      emit ReadMailComplete();
    }
  }
  else if (POP3_State==UIDL_State_All || POP3_State==LIST_State_All) {
    if( mail_RAW.endsWith("\r\n.\r\n")) {
      emit Response_Ready();
    }
  }
  else {
    if ( mail_RAW.endsWith("\r\n") ) {
      emit Response_Ready();
    }
  }
}