繁体   English   中英

多线程客户端服务器

[英]Multi threaded client server

嗨,我正在编写多线程客户端服务器的作业。 到目前为止,我所做的是在端口中打开一个套接字,并派生了两个线程来侦听和写入客户端。 但是我需要将两种类型的客户端连接到服务器,并为它们提供不同的服务。 我的问题是我最好的方法是什么?

我正在一个有无限循环来接受连接的类中处理连接。 只要接受了连接,该类就会创建两个线程来读写客户端? 现在,如果我要处理另一个不同类型的客户,我们该怎么办?

我需要打开另一个端口吗? 还是可以通过同一端口进行服务? 也许可以确定套接字中的客户端类型,而不是我可以不同地处理消息。

还是您建议这样?

  1. 为两种类型的客户端分叉两个线程,并在不同端口的每个线程中监视入站连接。
  2. 当一个连接被接受时,每个线程产生另一个两个线程进行监听和写入。

请提出建议。

也许您会从Unix用户那里得到更好的答案,但是我会提供我所知道的。

您的服务器需要一个线程来打开“侦听”套接字,以等待传入连接。 为了简单起见,该线程可以是主线程,但是,例如,如果您担心UI交互,则可以是备用线程(在Windows中,这是一个问题,对于Unix不确定)。 听起来您至少到现在为止。

当“侦听”套接字接受连接时,您将获得一个已连接到“客户端”套接字的“已连接”套接字。 您可以将此“已连接”套接字传递给一个新线程,该线程管理“已连接”套接字的读取写入。 因此,我建议进行的一项更改是在单个线程中管理“已连接”套接字,而不是像您那样在两个单独的线程(一个用于读取,一个用于写入)中进行管理。 阅读和写作对同一插座可以使用来实现select()系统调用,如这里

当新的客户端连接时,您的“侦听”套接字将提供一个新的“已连接”套接字,您将移交给另一个线程。 此时,您有两个线程-一个线程管理第一个连接,另一个线程管理第二个连接。 就套接字而言,客户端之间没有区别。 您仅具有两个打开的连接,两个客户端各有一个。

在这一点上,问题就变成了“为他们提供不同服务”是什么意思。 如果希望客户端以独特的方式与服务器交互,则必须以某种方式确定它。 可以根据您可以查询的“客户端”套接字的IP地址来确定交互,但这似乎是任意的,并且会受到网络变化的影响。 它也可以基于从“客户端”套接字接收的初始数据块,该数据块指示所需的交互类型。 在这种情况下,管理“已连接”套接字的线程可以读取套接字以获取预期的交互类型,然后将套接字交给管理该交互类型的类对象。

我希望这有帮助。

您可以在一个线程中处理单个客户端连接上的读写。 基于多线程的最简单解决方案是:

// C++ like pseudo-code
while (server_running)
{
    client = server.accept();
    ClientHandlingThread* cth = CreateNewClientHandlingThread(client);
    cth->start();
}

class ClientHandlingThread
{
    void start()
    {
         std::string header = client->read_protocol_header();
         // We get a specific implementation of the ProtocolHandler abstract class
         // from a factory, which create objects by inspecting some protocol header info. 
         ProtocolHandler* handler = ProtocolHandlerFactory.create(header);         
         if (handler)
             handler->read_write(client);
         else
            log("unknown protocol")
    }    
};

为了更好地扩展,您可以使用线程池,而不是为每个客户端生成新线程。 有许多C ++的 免费线程池实现。

while (server_running)
{
    client = server.accept();
    thread_pool->submit(client);
    cth->start();
}

通过使用一些实现反应堆模式的框架,可以进一步改善服务器。 他们在后台使用selectpoll功能。 您可以直接使用这些功能。 但是对于生产系统,最好使用现有的反应堆框架。 ACE是用于开发高度可扩展的并发应用程序的最广为人知的C ++工具包之一。

通常在不同的端口上服务于不同的协议。 但是,可以通过协商要使用的协议来在同一端口上为两种类型的客户端提供服务。 这可以像客户端发送HELOEHLO来请求一种或另一种服务那样简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM