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

TCP 应用协议 – 基于 TCP/IP 的进程间通信

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.33/5 (5投票s)

2019 年 9 月 8 日

MIT

5分钟阅读

viewsIcon

17576

downloadIcon

1371

TCP 应用协议是一种 IPC(进程间通信)机制,旨在为应用程序之间提供通用的远程接口。

最新的代码和发布包可在 GitHub 和 NuGet 上获取。

引言

TCP 应用协议是一种构建在 TCP(传输控制协议)之上的服务器/客户端文本消息协议。TCP 应用协议是一个高级通信协议,旨在为应用程序提供一个通用的远程接口,可以轻松集成到任何应用程序中,并且在服务器和客户端应用程序的开发人员只需最少的编码工作。

为什么选择 TCP?

两个应用程序之间的通信通常称为 IPC(进程间通信)。IPC 有许多种方式。TCP/IP 是其中一种。TCP/IP 的优势在于通信的应用程序可以运行在不同的计算机和不同的位置。由于互联网也基于 TCP/IP 工作,因此远程应用程序可以通过互联网进行通信。TCP/IP 完全独立于平台,是标准化的,并且被所有操作系统(以及许多其他设备)所实现。参考:Code Project - A Complete TCP Server/Client Communication and RMI Framework in C# .NET – Implementation

TCP 应用协议的优势

TCP 应用协议是一种服务器/客户端实现,其中服务器应用程序将响应客户端应用程序发起的请求。使用 TCP 应用协议,应用程序特定的命令可以由服务器应用程序轻松定义。每个注册的命令关键字可以包含一个或多个可选或强制参数,按需配置。传入的客户端消息将针对注册的命令集进行验证,并解析和分配定义的参数。开发人员可以专注于每个命令的实现。

作为一种人类可读的文本消息协议,在服务器和客户端之间传递的消息无需进行机器码的翻译和解释。此外,客户端应用程序可以轻松检索服务器应用程序上注册的命令,而无需参考用户手册或代码。

通过 TcpAppServerPlugin 类,可以在稍后阶段轻松开发和添加插件组件的命令集到宿主应用程序,而无需重新构建宿主应用程序。此外,客户端应用程序可以远程实例化服务器应用程序上的对象。一次允许连接到服务器的客户端数量也可以配置。

关于 TCP 应用协议

任何 TCP 客户端,包括 realterm,都可以用来与实现 TCP 应用协议的应用程序进行交互,因为该协议是使用人类可读的文本消息实现的。

通常,客户端和服务器之间的命令定义如下:

  • 从客户端发送的命令以命令关键字开头,后面跟着该命令定义的任何参数,并以回车符(\r, 0x0D)结束。多余的参数将被忽略。
    <Command Keyword> [Parameter0] … [ParameterN]
  • 服务器到客户端的响应也以 command 关键字开头,后面跟着 statusresponse messageStatus 标志是 OKERR
    <Command Keyword> <Status> <Response Message / Return Value>

TCP 应用服务器具有预定义的命令集,用于检索有关服务器应用程序、已注册命令和插件的信息,旨在简化客户端和服务器应用程序之间的集成过程。只需向服务器发送 Help 命令,即可返回已注册命令的列表。其他命令,如 FunctionList?ApplicationName?ApplicationVersion?,用于从服务器应用程序向已连接的客户端返回信息。

TCPAppClientTerminal 是 TCP 客户端实现的一个示例。编译后的二进制文件和源代码均可下载。下图显示了一个简单的 TCP 应用客户端终端正在运行。

TCP 应用架构

TcpAppServer(TCP 应用服务器)和 TcpAppClient(TCP 应用客户端)分别派生自 TcpServerTcpClient,它们是通用的 TCP 通信对象。

开始使用 TCP 应用服务器

  • 将 NuGet 包 CodeArtEng.Tcp 安装到项目中。
  • 创建 TcpAppServer 对象。
  • (可选)定义连接时返回给客户端的欢迎消息。
  • (可选)订阅 ClientConnectedClientDisconnected 事件。
  • 启动服务器。
  • 应用程序退出时应停止并释放服务器,以释放执行线程。
//Setup
AppServer = new TcpAppServer(this);
AppServer.WelcomeMessage = "Welcome to TCP Application Server";
AppServer.ClientConnected += AppServer_ClientConnected;
AppServer.ClientDisconnected += AppServer_ClientDisconnected;
AppServer.Start(12000);
//Termination
AppServer.Stop();
AppServer.Dispose();

注册应用程序特定命令

  • 可以使用 RegisterCommand 方法将命令注册到服务器应用程序。
  • 可选和强制参数可以作为 TcpAppParameter 对象添加到命令中。
  • 每个命令都应与定义其实现的 callback 函数相关联。
//TCP Application Server Customization Test
AppServer.RegisterCommand("CustomFunction", 
                          "Dummy Custom Function", customFunctionCallback);
AppServer.RegisterCommand("CustomFunction2", "Dummy Custom Function with Parameter", 
                           customFunction2Callback,
    new TcpAppParameter("P1", "Parameter 1"),
    new TcpAppParameter("P2", "Parameter 2, optional.", "10"));

使用插件

插件为应用程序提供了极大的可扩展性,可以在以后添加新功能和组件。TCP 应用协议具备处理和扩展插件组件中命令集的能力,以及实例化服务器应用程序中的对象,让我们来看看如何操作。

插件组件的准备

  • 将 NuGet 包 CodeArtEng.Tcp 安装到插件项目中。
  • 在插件类中实现 ITcpAppServerPlugin 接口。
  • 使用 TcpAppServerPlugin 作为 base 类或在插件类中作为 private 对象来创建插件实现类。TcpAppServerPlugin 类将与 TcpAppServer 交互以进行命令注册和执行。
  • 使用 TcpAppServerPlugin 对象将命令从插件组件注册到宿主应用程序。
  • 确保 ExecutePluginCommandShowHelp 方法调用 TcpAppServerPlugin 对象中的相应方法。
//Example plugin implementation
public class TcpAppServerSamplePlugin : ITcpAppServerPlugin
{
    private readonly TcpAppServerPlugin TcpAppPlugin;

    public string Name { get; set; }

    public string Alias { get => Name; set => Name = value; }

    public void ExecutePluginCommand(TcpAppInputCommand sender)
    {
        TcpAppPlugin.ExecutePluginCommand(sender);
    }

    public TcpAppServerSamplePlugin()
    {
        TcpAppPlugin = new TcpAppServerPlugin();
        TcpAppPlugin.RegisterCommand("PluginCommand1", "Plugin Command 1", 
                                      delegate (TcpAppInputCommand sender)
            {
                sender.Status = TcpAppCommandStatus.OK;
                sender.OutputMessage = "Command 1 Executed!";
            });
    }

    public bool DisposeRequest() { return true; }

    public void ShowHelp(TcpAppInputCommand sender)
    {
        TcpAppPlugin.ShowHelp(sender);
    }
}

将插件组件添加到服务器应用程序

在服务器应用程序中,在创建 TcpAppServer 时使用 AddPlugin 方法将其包含插件组件对象。确保每个插件组件的别名是唯一的,这一点很重要。此方法专为服务器应用程序实例化的对象而设计。

或者,插件对象可以由客户端应用程序实例化。为此,必须首先使用 RegisterPluginType 方法将允许的插件类型注册到 TcpAppServer。只允许注册 ITcpAppServerPlugin 对象类型。

//Example
TcpAppServerSamplePlugin SamplePlugin = new TcpAppServerSamplePlugin();
AppServer.RegisterPluginType("SamplePlugin", typeof(TcpAppServerSamplePlugin));

可以通过从客户端向服务器发送 Help <Alias> command 命令来检索与插件对象关联的命令。要执行插件对象中的命令,只需发送 Execute <Alias> <Command Keyword> [Parameters]

管理已连接的客户端

如果您的服务器应用程序对同时连接的客户端数量没有限制,则无需执行任何操作。否则,您可以使用 MaxClients 属性来限制连接的客户端数量。或者,我们也可以订阅 ClientConnected 事件来接受或拒绝传入的连接。

历史

  • 2019 年 9 月 8 日 - 首次发布
© . All rights reserved.