65.9K
CodeProject 正在变化。 阅读更多。
Home

带 HTTP 服务器示例的多线程服务器类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.79/5 (25投票s)

2001 年 8 月 13 日

4分钟阅读

viewsIcon

190590

downloadIcon

10383

带 HTTP 服务器示例的多线程服务器类

引言

本文涵盖以下主题

  • Win32 线程
  • 同步对象
  • 异步套接字
  • 基本 HTTP 协议
  • 使用抽象类
  • STL

详细说明

在编写套接字服务器时,我必须在单线程技术和多线程技术之间进行选择。我发现多线程技术有几个优点,包括以下几点:
  • 使用 WSAWaitForMultipleObjects(...) 时,无需处理 64 个句柄的限制。
  • 无需费力地将大文件传递给客户端而不延迟其他请求。
尽管这些优点使得多线程服务器在许多情况下都非常适合,但它们并不能证明多线程服务器在任何地方都适用。例如,如果计算机运行的服务器组件性能不高,静态线程解决方案可能是最佳选择。下文将介绍一个基于异步套接字的多线程服务器实现。我以我的服务器类为基础构建了一个 Web 服务器作为示例。HTTP 的实现只是为了响应基本的 HTTP 请求。那么,让我们通过一些实现细节来了解一下。

实现

有一定数量的线程始终处于活动状态,等待或处理某些事务。第一个重要的线程是 AcceptThread。它的职责是初始化套接字库并监听所有传入的连接。每次有新连接到达时,都会创建一个新线程。这个新线程称为 ClientThread,它的职责是处理新连接客户端的需求。当客户端断开连接时,关闭线程句柄的请求将通过 HandleList 对象传递给 HelperThread。

接下来我将描述 CGenericServer 类中的一些重要函数的设计目的。这些函数按照它们在源代码中的实现顺序出现。

  • GetStats(...) - 返回有关流量、连接的唯一 IP 地址的访问者数量、服务器的总请求数以及当前连接到服务器的客户端数量等有用统计信息。

  • AddClient(...) - 通知派生类新的连接到达,并创建一个工作线程来处理子套接字的需求。

  • Run(...) - 启动 Accept 和 Helper 线程。

  • Shutdown(...) - 终止 Accept 和 Helper 线程,并等待 ClientThreads 也被终止。

  • Reset(...) - 将统计值重置为 0。

  • CleanupThread(...) - 清理 ClientThread 使用的所有已打开句柄和已分配内存。线程 ID 将传递给 HelperThread 以便通过此函数进一步终止。仅由 ClientThread 使用。

  • CleanupThread(...) - 关闭主监听套接字和一些句柄。仅由 AcceptThread 使用。

  • AcceptThread(...) - 处理所有传入连接的主工作线程。

  • ClientThread(...) - 处理所有已建立的客户端连接。

  • HelperThread(...) - 如果我没有使用 _endthread(...),则需要有人在线程不再活动后关闭其句柄。该函数被分配给 HelperThread

如果你的类派生自 CGenericServer,则应实现以下抽象函数:

  • IsComplete(...) - 这是一个非常重要的函数,需要仔细实现。你必须根据调用此函数时收到的数据来确定整个消息是否已在缓冲区中。在我提供的 HTTP 服务器示例中,条件是双 \r\n。

  • ParseRequest() - 这也是一个非常重要的函数。它将向你提供从客户端接收到的数据,并需要你返回响应数据。如果你返回 false,连接将立即关闭,线程也将被终止。否则,连接将保持打开状态,除非你将来将 KeepAlive 变量设置为 1。你将在我的示例中找到基本的 HTTP 实现。

  • GotConnection(...) - 这将向你提供连接客户端的 IP 地址和端口号。

  • DataSent(...) - 每次将数据发送到客户端时,它都会通知你,并给出发送的字节数。

补充说明

我的 HTTP 服务器支持两个最常见的 HTTP 错误:

  • 404 资源未找到
  • 504 方法未实现

这些错误都有相应的 HTML 文件。这些文件的名称目前硬编码在 HTTPServer.h 中。这些文件必须位于服务器的根目录下。

我还向 CHTTPServer 类添加了几个 MIME 类型,以便浏览器可以识别这些类型。当然,还有更多可用的类型。一个简单的 CLog 类被用来记录可能发生的任何错误。日志文件将放置在 Windows 目录下,默认文件名是 UMServer.log

这不是一个功能齐全的 HTTP 服务器,也没有实现 HTTP 协议的所有功能,因为这不是本项目的目标。

© . All rights reserved.