Как мне предотвратить поздние ответы на сокет TCP?

#c #sockets #connection-pooling

#c #сокеты #объединение в пул соединений

Вопрос:

Я пишу библиотеку базы данных, которая должна будет разумно поддерживать тайм-ауты. Теперь, когда я смотрю на объединение в пул соединений, меня особенно беспокоит следующий сценарий:

  1. Отправить запрос #1
  2. Время ожидания истекло через n секунд.
  3. Отправить запрос #2
  4. Получение ответа на запрос # 1

Четвертый шаг может произойти, потому что запросы не помечены идентификатором запроса: все, что я знаю, это то, что я получил ответ, и я не знаю, какому запросу он принадлежит. Можно было бы возразить, что это представляет собой ошибку в протоколе, но это зависит не от меня.

Перед отправкой запроса № 2, что я должен сделать с сокетом, чтобы избежать такого позднего ответа? Это единственный правильный способ shutdown() close() и повторно connect() ?

Комментарии:

1. Как насчет добавления константы в select всех запросов, чтобы ваша библиотека могла определить, для какого запроса предназначен ответ?

2. Это отличная идея, но, к сожалению, не очень хорошая для библиотеки. Возможно, через плагин…

Ответ №1:

Я боюсь, что это единственный безопасный способ управлять вашим соединением, потому что нет другого способа получить однозначный ответ между вопросом и ответом по TCP. Похоже, между ними отсутствует какая-то функция отмены.

Эта ссылка дает больше информации: http://www.ssfnet.org/Exchange/tcp/tcpTutorialNotes.html

Комментарии:

1. В свою очередь, это потому, что TCP ничего не знает о ваших так называемых «запросах», «ответах» или «отменах». Подключенный сокет — это всего лишь две однонаправленные трубки для байтов (Тед Стивенс был прав). Если один конец записывает материал, а поток не поднимается, тогда другой конец может его прочитать. Итак, определение того, для какого «запроса» предназначен этот «ответ», является проблемой уровня приложения. Либо он встроен в протокол, который определяет запрос / ответ, либо он не существует.

2. Я имею в виду, я знаю. 🙂 Но у TCP есть порядковые номера, поэтому я надеялся, что есть какой-то трюк, который я мог бы использовать.

3. @Andres: к сожалению, порядковые номера просто позволяют уровню TCP собирать поток — нечего сказать, сколько времени прошло между конкретными байтами в противоположных направлениях. Помните, что только потому n , что с момента отправки первого запроса прошло несколько секунд, это не означает n , что с момента его прочтения на другом конце прошло несколько секунд. Таким образом, другой конец, возможно, отправил этот ответ до истечения времени ожидания от своего POV, но он прибыл к вам после истечения времени ожидания от вашего POV. Одни только тайм-ауты могут работать с надежным, синхронизированным по времени соединением, которым TCP не является.