1

我想实现和单元测试(不一定是TDD)与某个应用协议中使用的TCP服务器进行通信的客户端应用程序。客户机/服务器 - 如何从网络逻辑中分离协议?

我在here (1)here (2)这样的地方见过,协议代码应该最好从网络代码中分离出来,这样我可以单独对每一个进行单元测试。

但是我无法理解我应该如何设计和实现这些部分。

第一个链接使用方法HelloMessage()HowdyMessage()讨论MyProtocolHandler类。这是否意味着协议处理程序预计会有两种方法来生成消息并处理响应?我将如何使用它们?还有一件事,每个消息/响应对应该有不同的ProtocolHandler类,或者只有一个类适用于所有消息/响应对?

第二个链接说的是ReaderWriter。再次,我不能说我应该如何使用它们。

这两个只是例子。主要问题是,我怎样才能从网络中分离出逻辑并对其进行单元测试?我必须说我还没有尝试过任何东西;我习惯于编写耦合的代码,不知道从哪里开始。

回答

1

这些是不同的方法来处理任务。网络堆栈被设计为不同的层,其中每个层向上层提供“定义良好”的功能,并且它通过API提供这些功能。

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

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

现在你的协议A可以是仅由一个类或一组类来实现。如果它是一组类,我建议你让它们成为同一个包的一部分。

详细阐述如何实现它,我会建议两个选项: 1)您有一个Reader和Writer类,它们是套接字的包装器。然后你的协议类使用这些读者和作者,你可以测试它,而不必使用一个没有使用套接字的儿童读者和作者的网络。 2)这更复杂一些,你可以有一个通信类,可以接收消息通过消息队列发送,也可以使用另一个消息队列发送收到的消息。 Communication类知道如何处理连接或套接字(取决于抽象级别)。它知道如何打开连接,处理超时等。这是一个更好的设计,但太复杂。

我希望这会有所帮助。

+0

这正是我如何实现它,使用一个类。然而,我对这个问题中链接文本的理解是,可以从实现API(协议代码)的代码中分离使用套接字的代码(网络代码),这样我就可以测试后者而不必实际上执行网络。如何做到这一点是我无法理解的。 – Piovezan

+0

@Piovezan,我增加了更多的信息,但你必须努力工作,并提出一个设计。从简单的事情开始,然后你会开始找出更好的方法来做到这一点。 – rodolk

+0

我会尝试选项1.在选项2中,消息队列是指完整的选项,如RabbitMQ或常规Java队列? – Piovezan