【问题标题】:Handing over an established TCP connection from one process to another将已建立的 TCP 连接从一个进程移交给另一个进程
【发布时间】:2013-08-21 18:38:14
【问题描述】:

我正在用 C++ 编写一个简单的 Web 服务器来处理长期连接。但是,我需要不时重新加载我的网络服务器。我想知道是否有一种方法可以将已建立的连接从一个进程移交给另一个进程,以便在重新加载后能够保留已建立的连接。

仅传递文件描述符就足够了吗?连接状态会发生什么? 有没有类似的开源项目做同样的事情?

有什么想法或想法吗?

谢谢,

【问题讨论】:

  • 您所要做的就是传递文件描述符,但是,在父子进程关系之外执行此操作要困难得多。你打算让旧的网络服务器启动新的吗?
  • 是的,可能。我宁愿暂时没有父子进程。

标签: c++ linux network-programming


【解决方案1】:

我真的不知道这是否可能,但我认为不可能。如果你fork() 那么孩子将“继承”描述符,但我不知道它们的行为是否像应该的那样(尽管我怀疑它们确实如此。)并且通过分叉,你不能运行新代码(你能?) 简单的描述符编号是特定于进程的,因此仅将它们传递给一个新的、不相关的进程也不起作用,并且当您的进程终止时它们将被关闭。

一种解决方案(在没有更简单的解决方案的情况下)是将您的服务器分成两个进程:

  1. 前端:一个非常简单的进程,它只接受连接,保持连接打开并将接收到的任何数据转发给第二个进程,反之亦然。
  2. 服务器:真正的网络服务器,执行所有逻辑和处理,但不直接与客户端通信。

第一个和第二个进程通过一个简单的协议进行通信。该协议的一个特性必须是它确实支持被终止和重新启动的第二个进程。

现在,您可以在不丢失客户端连接的情况下重新加载实际的服务器进程(因为它们是由前端进程处理的。)而且由于这个前端非常简单并且可能只有很少的配置和错误,所以您很少需要重新加载它。 (我假设您需要重新加载服务器进程,因为它遇到需要修复的错误或者您需要更改配置和内容。)

此系统可以具有的另一个重要且有用的功能是能够“逐步”在服务器进程之间进行转换。也就是说,您已经有一个前端和一个正在运行的服务器,但您决定重新加载服务器。您启动 另一个 连接到前端的服务器进程(当旧服务器仍在运行和连接时),前端进程将所有新客户端连接转发到新服务器进程(或甚至来自现有客户端连接的所有新请求。)当旧服务器完成处理它正在处理的所有请求时,它会优雅而干净地退出。

正如我所说,这是一个您可能会尝试的解决方案只有在没有发现更简单和更简单的情况下。

【讨论】:

  • 仅供参考:连接 TCP 套接字并分叉(并执行)一个新的子进程正是 inetd 守护进程所做的,因此如果父进程持有套接字并且子进程继承它,则它是可能的。
  • 没错!谢谢你指出这一点。因此,连接的套接字描述符 do 在 fork+exec 中存在。所以,所有 OP 需要做的就是执行下一个服务器进程(创建父/子关系)并以某种方式告诉它有趣的描述符是什么。
  • @DaveS:你能写一个答案,多描述一下吗?我确信这将是一种比我的解决方法更合适的技术。
  • 感谢您的回复。我想指出,虽然我的网络服务器有代理连接(其中我的网络服务器实际上是客户端)。这些连接也应该移交。
  • 我搜索了一下,我看到了 send_fd 和 recv_fd。还有一个包装库。 normalesup.org/~george/comp/libancillary 有什么想法吗?
猜你喜欢
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 2012-08-26
  • 2018-01-31
相关资源
最近更新 更多