多线程服务器问题

Posted

技术标签:

【中文标题】多线程服务器问题【英文标题】:Multithreaded Server Issue 【发布时间】:2010-02-14 14:57:22 【问题描述】:

我正在用 linux 编写一个服务器,它应该提供一个 API。

最初,我想让它在单个端口上实现多线程,这意味着我将有多个线程处理在单个端口上收到的各种请求。

我的一个朋友告诉我,这不是它应该的工作方式。他告诉我,当收到请求时,我首先必须遵循Handshake 过程,创建一个线程来监听其他专用于该请求的端口,然后将请求的客户端重定向到新端口。

理论上,这很有趣,但我找不到任何关于如何实现握手和重定向的信息。有人可以帮忙吗?


如果我在解释您的响应时没有错,一旦我创建了一个带有主线程监听端口的多线程服务器,并创建了一个新线程来处理请求,我实质上就是在单个端口上使其成为多线程?

考虑一下我每秒收到大量请求的情况。端口上的每个请求现在都应该等待“当前”请求完成,这不是真的吗?如果没有,那还怎么通信:假设一个浏览器发送一个请求,那么处理这个请求的线程必须首先监听端口,阻塞它,处理它,响应然后解除阻塞。

这样,尽管我有“多线程”,但我使用的只是一个单独的线程,除了主线程之外,因为端口被阻塞了。

【问题讨论】:

两个(或更多)连接可以同时激活到同一个本地端口 - 这绝对没有问题,而且这是通常的工作方式。一个连接不会“阻止”任何其他连接 - 一旦创建,它们就完全独立。 嗨。感谢您的评论。我完全明白你的意思,事实上,这就是我感到困惑的地方。如果多个连接正在使用一个端口,这意味着两个不同的客户端正在连接同一个端口,那么如何正确完成读/写以及如何将信息发送到正确的客户端?我尝试阅读一些关于套接字和服务器编程的书籍/文章,但意识到我在错误的地方寻找解决方案。谁能推荐一个关于这个主题的简洁快速的指南? 从应用程序的角度来看,这两个连接由不同的套接字表示——不同的文件描述符。从传输 (TCP/IP) 的角度来看,这两个连接由不同的 (remote IPremote portlocal IPlocal port) 元组标识(地址的一个或两个远程部分将是不同)。 【参考方案1】:

你的朋友告诉你的类似于被动 FTP——客户端告诉服务器它需要一个连接,服务器发回端口号,客户端创建一个到该端口的数据连接。

但您想要做的只是多线程服务器。您所需要的只是一个服务器套接字侦听和接受给定端口上的连接。自动 TCP 握手完成后,您将从 accept 函数中获得一个新套接字 - 该套接字将用于与刚刚连接的客户端进行通信。所以现在您只需创建一个新线程,将该客户端套接字传递给线程函数。在您的服务器线程中,您将再次调用accept 以接受另一个连接。

【讨论】:

【参考方案2】:

TCP/IP 进行握手,如果您想不出任何理由进行握手,而不是您的应用程序不需要它。

应用程序特定握手的一个示例可能是用于用户身份验证。


您同事的建议听起来像是 FTP 的工作方式。这不是一件好事——如今的互联网或多或少地用于使用单个端口的协议,而拥有一个命令端口是不好的。原因之一是状态防火墙不是为多端口应用程序设计的。它们必须针对以这种方式执行的每个单独的应用程序进行扩展。

【讨论】:

【参考方案3】:

看看ASIO's tutorial on async TCP。其中一部分接受 TCP 上的连接并生成处理程序,每个处理程序都与单个客户端通信。这就是 TCP 服务器通常的工作方式(包括 HTTP/web,最常见的 tcp 协议。)

如果您设置为每个连接创建一个线程,您可以忽略 ASIO 的异步内容。它不适用于您的问题。 (完全异步并且每个内核有一个工作线程很好,但它可能无法与您的环境的其余部分很好地集成。)

【讨论】:

以上是关于多线程服务器问题的主要内容,如果未能解决你的问题,请参考以下文章

多线程游戏服务器的基本设计?

多线程服务器不等待客户端连接就退出

与记录器线程的多线程应用程序交互

l versC#多线程问题

C++ 多线程服务器帮助

多线程:防止 Visual Studio 阻塞特定线程 [重复]