Как реализовать неблокирующий tcp сервер с механизмом ack? - PullRequest
0 голосов
/ 23 апреля 2019

Я новичок в программировании многопоточного веб-сервера. Сейчас я пишу серверную программу, которая:

  1. получает сообщения (в формате данных, определяемых пользователем) из сокета tcp
  2. Процессэти сообщения (это занимает время)
  3. Отправка соответствующих ответов в сокет
  4. Предоставление механизма ACK для получения сообщений и отправки ответов, то есть каждое сообщение содержит уникальный номер seq, и я должен включить ack(аналогично seq) в соответствующем ответе.Другая сторона также реализует этот механизм.Если я не получал ACK от другой стороны в течение 5 минут, мне следует повторно отправить сообщение, от которого я ожидал получить соответствующий ACK.

Я думал использовать цикл while для получения сообщенийиз сокета, затем обработайте сообщения и отправьте ответы.

Проблема в том, что обработка сообщений занимает много времени, и я могу получить несколько сообщений за короткий период.Так что если я вызову функцию process_message () в этом цикле while и дождусь его завершения, он будет блокирован, и я определенно потрачу время.Поэтому мне нужен неблокирующий способ.

Я провел некоторое исследование.Я предположил, что могу использовать две общие технологии: пул потоков и очередь сообщений.

Для пула потоков моя идея выглядит следующим образом: псевдокод:

def process_message():
  process_message // takes time
  send_response(socket)

while True:
  message = recv(socket)
  thread = thread_pool.get_one()
  thread.start(target=process_message)

Для очереди сообщений я не являюськонечно, но моя идея заключалась бы в том, чтобы иметь нить производителя и потребителя:

def consumer:
  // only one consumer thread?
  message = queue.poll()
  consumer_thread.process_message(message)
  send_response(socket)


while True:
  // only one producer thread?
  message = recv(socket)
  producer_thread.put_message_to_queue()

Надеюсь, моя идея ясна.Кто-нибудь может предложить какое-нибудь типичное решение?

Тогда, уловка, есть мысли о том, как реализовать механизм ACK?

Спасибо!

1 Ответ

1 голос
/ 24 апреля 2019

Это довольно широко, потому что все еще слишком много для реализации.

Общая идея действительно заключается в том, чтобы реализовать:

  • сервер TCP, который будет принимать входящие сообщения и писатьих (включая сокет, из которого они были получены) в очереди
  • пул рабочих потоков, которые получат сообщение из очереди, обработают сообщение и передадут ответ объекту, отвечающему за отправкусообщение и дождитесь подтверждения
  • объекта, который отправит ответы, сохранит порядковый номер, сокет и сообщение, пока ответ не будет подтвержден.Поток будет удобен для обработки списка сообщений, ожидающих подтверждения, и отправки их снова, когда истечет время ожидания.

Но каждая часть требует определенного объема работы и может быть реализована различными способами.(select, TCPServer или потоки, обрабатывающие принятые сокеты для первого, какая структура данных для хранения сообщений, ожидающих подтверждения для третьего, и какая реализация пула для второго).Я сделал несколько тестов и понял, что полный ответ будет намного выше, чем ожидается на этом сайте.ИМХО, вам лучше разбить вопрос на более мелкие ответные части, оставив этот вопрос в качестве общего контекста.

Вы должны также сказать, должны ли входящие сообщения быть немедленно подтверждены при получении или будут косвенно подтверждены ответом.

...