Почему этот вызов SSL_pending всегда возвращает ноль? - PullRequest
7 голосов
/ 08 июля 2011

Этот код предназначен для сервера HTTPS, использующего блокирующие сокеты:

  request := '';
  start := gettickcount;
  repeat
    if SSL_pending(ssl) > 0 then
      begin
      bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
      if bytesin > 0 then
        begin
        buffer[bytesin] := #0;
        request := request + buffer;
        end
      else break; // read failed
      end; // pending
   until (gettickcount - start) > LARGETIMEOUT;
   // "request" is ready, though possibly empty

SSL_pending () всегда возвращает ноль, а SSL_read () никогда не достигается.Если вызов SSL_pending () удален, выполняется SSL_read ().Почему SSL_pending () не указывает, сколько байтов доступно?

Обратите внимание, что если вы вызываете SSL_read () и количество возвращаемых байтов меньше размера вашего буфера, вы прочитали все и сделали.

Если входящие данные превышают размер буфера, первый вызов SSL_read () заполняет буфер, и вы можете повторять вызов SSL_read (), пока не сможете заполнить буфер.

НО если входящие данные в точности кратны размеру вашего буфера, последний кусок данных заполняет буфер.Если вы попробуете другой SSL_read (), думая, что в блокирующем сокете может быть больше данных, он зависнет на неопределенное время.Отсюда и желание проверить SSL_pending () в первую очередь.И все же это не работает.

Как избежать зависания окончательного SSL_read ()?(Я не могу себе представить, что ответ должен быть неблокирующим, поскольку это означает, что вы никогда не сможете использовать SSL_read с блокировкой.)

ОБНОВЛЕНИЕ: Следующие работы.Очевидно, SSL_pending () не работает до тех пор, пока после первого SSL_read ():

  request := '';
  repeat
    bytesin := SSL_read(ssl, buffer, sizeof(buffer)-1);
    if bytesin > 0 then
      begin
      buffer[bytesin] := #0;
      request := request + buffer;
      end
    else break; // read failed
  until SSL_pending(ssl) <= 0;
  // "request" is ready, though possibly empty

Ответы [ 2 ]

6 голосов
/ 08 июля 2011

Вы используете SSL_pending() совершенно неверный путь. OpenSSL использует конечный автомат, где SSL_pending() указывает, есть ли у конечного автомата какие-либо ожидающие байты, которые были буферизованы и ожидают обработки. Поскольку вы никогда не вызываете SSL_read(), вы никогда не буферизуете какие-либо данные и не продвигаете конечный автомат.

2 голосов
/ 03 апреля 2012

Если функция SSL_pending возвращает код возврата 0, это не обязательно означает, что нет данных, немедленно доступных для чтения в сеансе SSL.Код возврата 0 указывает, что в текущей записи данных SSL больше нет данных.Однако больше записей данных SSL, возможно, уже было получено из сети.Если функция SSL_pending возвращает код возврата 0, выполните функцию select, передав дескриптор файла сокета, чтобы проверить, доступен ли сокет для чтения.Читаемый означает, что больше данных было получено из сети на сокете.

...