Client/server - 如何将协议与网络逻辑分开?

Client/server - How to separate protocol from network logic?

我想实现和单元测试(不一定是 TDD)客户端应用程序,它使用特定应用程序协议与 TCP 服务器通信。

我在 here (1) and here (2) 等地方看到协议代码最好与网络代码分离,这样我就可以分别对每个代码进行单元测试。

但是我不明白我应该如何设计和实现这些部分。

第一个 link 讨论 MyProtocolHandler class 方法 HelloMessage()HowdyMessage()。这是否意味着协议处理程序应该有两种方法来生成消息和处理响应?我将如何使用它们?还有一件事,每个 message/response 对应该有不同的 ProtocolHandler class 还是所有的只有一个?

第二个link讲了一个Reader和一个Writer。同样,我无法理解应该如何使用它们。

这两个只是例子。主要问题是,如何将逻辑与网络分离并对它们进行单元测试?我不得不说我还没有尝试过任何东西;习惯了只写耦合代码,不知从何下手

这些是处理任务的不同方法。网络堆栈被设计为不同的层,其中每一层为上层提供 "well defined" 功能,并通过 API 提供这些功能。

因此,如果您想在 TCP 或 SSL 上实现您自己的应用层协议 运行ning(反过来可能 运行 在 TCP 上),您将使用套接字接口。设计该部分的方式与设计任何应用程序的方式相同。通常,您希望将应用程序逻辑与协议分开,称之为 A,逻辑。您的协议 A 将负责使用套接字(写入和读取)向服务器发送消息,从服务器读取消息,处理超时(例如,当期望服务器的响应永远不会到达时),处理套接字错误、消息格式、消息解析等。协议 A 将从您的应用程序中隐藏所有这些问题。

您的应用程序将只处理您的协议提供的 API 函数:像 HelloMessage 一样,它会调用该方法并在内部,HelloMessage 将处理套接字、消息格式等。

现在你的协议 A 只能由一个 class 或一组 class 实现。如果它是一组 classes,我建议您将它们作为同一个包的一部分。

详细说明如何实施它,我建议两个选项: 1) 你有一个 Reader 和 Writer class 是套接字的包装器。然后你的协议 classes 使用这些读者和作家,你可以在没有网络的情况下测试它 Reader 和不使用套接字的作家。 2) 这更复杂,您可以有一个 Communication class,它可能接收要通过消息队列发送的消息,它也可以使用另一个消息队列发送接收到的消息。 Communication class 知道如何处理连接或套接字(取决于抽象级别)。它知道如何打开连接、处理超时等。这是一个更好的设计,但太复杂了。

希望对您有所帮助。