【问题标题】:kernel-based (Linux) data relay between two TCP sockets两个 TCP 套接字之间基于内核 (Linux) 的数据中继
【发布时间】:2013-07-09 13:46:09
【问题描述】:

我编写了 TCP 中继服务器,它的工作方式类似于点对点路由器(超级节点)。

最简单的情况是两个打开的套接字和它们之间的数据中继:

clientA 服务器 clientB

但是,服务器必须为大约 2000 个这样的 A-B 对提供服务,即。 4000 个套接字...

userland 中有两个众所周知的数据流中继实现(基于 socketA.recv() --> socketB.send()socketB. recv() --> socketA.send()):

  • select / poll 函数的使用(非阻塞方式)
  • 使用线程/分叉(阻塞方法)

我使用了线程,所以在最坏的情况下服务器会创建 2*2000 个线程!我不得不限制堆栈大小并且它有效,但它是正确的解决方案吗?

我的问题的核心:

有没有办法避免用户空间中两个套接字之间的活动数据中继?

似乎有一种被动的方式。例如,我可以从每个套接字创建文件描述符,创建两个管道并使用 dup2() - 与标准输入/输出重定向相同的方法。然后两个线程对数据中继无用,可以完成/关闭。 问题是服务器是否应该关闭套接字和管道,以及如何知道管道何时损坏以记录事实?

我还找到了“套接字对”,但我不确定它是否符合我的目的。

您会建议什么解决方案来卸载用户空间并限制线程数量?

一些额外的解释:

  • 服务器已定义静态路由表(例如,ID_A 和 ID_B - 配对标识符)。客户端 A 连接到服务器并发送 ID_A。然后服务器等待客户端 B。当 A 和 B 配对时(两个套接字都打开),服务器启动数据中继。
  • 客户端是对称 NAT 后面的简单设备,因此 N2N 协议或 NAT 穿越技术对它们来说过于复杂。

感谢 Gerhard Rieger,我得到了提示:

我知道有两种内核空间方法可以避免读/写、接收/发送 用户空间:

  • 发送文件
  • 拼接

两者都有关于文件描述符类型的限制。

dup2 不会帮助在内核中做某事,AFAIK。

手册页:splice(2)splice(2)vmsplice(2)sendfile(2)tee(2)

相关链接:

【问题讨论】:

  • 对于这么多的连接,几个线程和epoll(4) 的组合可能是你应该研究的。
  • 那个,你可以使用类似libev
  • 谢谢。然而,它仍然是用户态的活跃中继。我相信存在一种被动的方法。服务器以 5 秒超时等待客户端 ID,因此线程似乎是配对阶段的自然选择。
  • 很好的简短比较:win.tue.nl/~aeb/linux/lk/lk-12.html。我只是在每个线程中使用了阻塞 recv() 。但是为了限制线程,我可以在一个线程中使用 epoll() 或 FASYNC。
  • 其他提示:kegel.com/c10k.html

标签: sockets tcp kernel splice


【解决方案1】:

OpenBSD 实现 SO_SPLICE:

Linux 是否支持类似的东西或只有自己的内核模块是解决方案?

【讨论】:

    【解决方案2】:

    即使负载小到 2000 个并发连接,我也绝不会使用线程。它们具有最高的堆栈和切换开销,仅仅是因为确保您可以在任何地方被打断总是比您只能在特定位置被打断更昂贵。只需使用 epoll() 和 splice (如果您的套接字是 TCP,似乎就是这种情况),您会没事的。您甚至可以让 epoll 在事件触发模式下工作,您只需注册一次 fd。

    如果您绝对想使用线程,请为每个 CPU 内核使用一个线程来分散负载,但如果您需要这样做,这意味着您正在以亲和性、每个 CPU 插槽上的 RAM 位置等的速度进行游戏。 . 起着重要作用,在您的问题中似乎并非如此。所以我假设在你的情况下一个线程就足够了。

    【讨论】:

    • 谢谢。更好地使用 EPOLLONESHOT 或 ADD/DEL ?喜欢这里stackoverflow.com/questions/4173024/…rg4.net/archives/375.html
    • 从未尝试过 EPOLLONESHOT,尽管它可能很有用,并且可能是 EPOLLET 的优雅替代品。从标准的 ADD/DEL 开始,以限制我认为的复杂性,并在需要时尝试进行优化。
    猜你喜欢
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 2012-10-06
    • 1970-01-01
    • 2014-08-07
    • 2017-10-27
    相关资源
    最近更新 更多