Я новичок в программировании OpenSSL.В любом случае, я написал сервер и клиент openssl на C (также протестирован на C ++).Когда они соединяются, они успешно рукопожатие и могут читать и писать друг другу успешно.В настоящее время он настроен так, что клиент читает только из потока и записывает в буфер, например:
while((rc = SSL_read(ssl, buffer, sizeof(buffer))) > 0){
fprintf(stdout,"%s\n", buffer);
}
Аналогично, мой сервер настроен так, что он постоянно записывает в поток из буфера, например:
while ((rc = SSL_write(ssl, buffer, sizeof(buffer))) > 0) {
fprintf(stdout, "Sent message.\n");
}
fprintf(stdout, "Done sending.\n");
И это работает.Если бы я внезапно завершил работу клиента с помощью ^C
(Ctrl C), сервер завершил бы работу и напечатал «Done Sending».Однако, если бы я поместил задержку дольше, чем около 10000 наносекунд между каждым SSL_write (в рамках цикла записи сервера), я получаю неожиданное поведение, когда клиент отключается внезапно (используя ^C
) или обычно через счетчик и разрыв.Для пояснения, перед внезапным отключением сервер может использовать SSL_write, а клиент может использовать SSL_read в обычном режиме между любыми задержками (ничего не пытался в течение минуты).
Эта проблема означает, что клиентское соединениеможет эффективно привести к аварийному завершению потока сервера, о чем свидетельствует отсутствие печати «Готово к отправке» после отключения клиента при использовании задержек, превышающих 10000 наносекунд.Я не хочу, чтобы сервер был в состоянии сбоя из-за внезапного отключения в сеансе.Чтобы было ясно, что сервер вылетает при вызове SSL_write
и ничего не возвращает.
Я пытался решить эту проблему:
- Попытка увидеть изменения в этих возвратахзначения:
SSL_want(ssl)
, SSL_get_error(ssl,0)
, ERR_get_error()
и SSL_get_shutdown(ssl)
.В некотором тестовом коде я распечатал все это до вызова SSL_write
, и ни один из них не изменил свои значения перед сбоем. - Очистка очереди ошибок перед каждым
SSL_write
с использованием ERR_clear_error()
- Проверка того, напечатано ли что-нибудь с помощью
ERR_print_errors_fp(stderr)
- nada
Я использовал следующие методы задержки:
// Method 1
for(long i = 0; i < (long) 99999999; i++){}
// Method 2
struct timespec tim, tim2;
tim.tv_sec = 0;
tim.tv_nsec = 10000L; // 5 milliseconds
nanosleep(&tim, &tim2);
// Method 3
sleep(1)
Лично я считаю, что было бы нелепо требовать, чтобызапись в сокет в течение одной сотой миллисекунды, чтобы сервер не зависал при отключении клиента.
Это действительно ожидаемое поведение?Я делаю что-то не так или я что-то забываю?Что я должен сделать, чтобы обойти эту проблему?
Буду признателен за любую помощь или совет.