如何使用ack机制实现无阻塞TCP服务器?

时间:2019-04-23 14:04:27

标签: python multithreading tcp message-queue

我是多线程Web服务器编程的新手 现在,我正在编写一个服务器程序,该程序:

  1. 从tcp套接字接收消息(以自定义数据格式)
  2. 处理这些消息(这需要时间)
  3. 向套接字发送相应的响应
  4. 提供用于接收消息和发送响应的ACK机制,即每个消息都包含一个唯一的seq编号,我应该在相应的响应中包含ack(与seq相同)。另一方也实现了这种机制。如果我有5分钟没有收到对方的ACK,则应该重新发送希望从其接收相应ACK的消息。

我的想法是使用while循环从套接字接收消息,然后处理消息并发送响应。

问题是,处理消息需要时间,我可能会在短时间内收到多条消息。因此,如果我在此while循环中调用process_message()函数并等待其完成,它将被阻塞,并且我肯定会浪费时间。所以我需要非阻塞方式。

我做了一些研究。我以为我可能会使用两种常见的技术:线程池和消息队列。

对于线程池,我的想法类似于以下伪代码:

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 个答案:

答案 0 :(得分:1)

这是相当广泛的,因为还有很多东西要执行。

一般的想法确实是实现:

  • TCP服务器,它将接收传入的消息并将它们(包括接收消息的套接字)写入队列中
  • 工作线程池,该线程将从队列中获取消息,处理消息并将响应传递给负责发送消息并等待确认的对象
  • 一个对象,它将发送响应,存储序列号,套接字和消息,直到确认响应为止。线程可以方便地处理等待确认的消息列表,并在超时耗尽后再次发送它们。

但是每个部分都需要大量工作,并且可以通过不同的方式(selectTCPServer或第一个处理接受套接字的线程来实现,该数据结构用于存储等待消息的消息)确认第三个,并在第二个中实现哪个池)。我进行了一些测试,并意识到完整的答案将远远超出此站点上的预期。恕我直言,您最好将问题分解成较小的可回答部分,并始终将其保留为一般情况。

您还应该说传入的消息是在收到消息后立即被确认还是在响应中被隐式确认。