TCP 应用协议 – 基于 TCP/IP 的进程间通信
TCP 应用协议是一种 IPC(进程间通信)机制,旨在为应用程序之间提供通用的远程接口。
- 下载源代码 - 89.9 KB
- 下载 TcpServerExample - 26.1 KB
- 下载 TcpClientExample - 24.5 KB
- 下载 TcpAppClientTerminal - 23.5 KB
最新的代码和发布包可在 GitHub 和 NuGet 上获取。
- GitHub: https://github.com/Code-Artist/CodeArtEng.Tcp
- NuGet: https://nuget.net.cn/packages/CodeArtEng.Tcp/
引言
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
关键字开头,后面跟着status
和response message
。Status
标志是OK
或ERR
。<Command Keyword> <Status> <Response Message / Return Value>
TCP 应用服务器具有预定义的命令集,用于检索有关服务器应用程序、已注册命令和插件的信息,旨在简化客户端和服务器应用程序之间的集成过程。只需向服务器发送 Help 命令,即可返回已注册命令的列表。其他命令,如 FunctionList?
、ApplicationName?
、ApplicationVersion?
,用于从服务器应用程序向已连接的客户端返回信息。
TCPAppClientTerminal
是 TCP 客户端实现的一个示例。编译后的二进制文件和源代码均可下载。下图显示了一个简单的 TCP 应用客户端终端正在运行。
TCP 应用架构
TcpAppServer
(TCP 应用服务器)和 TcpAppClient
(TCP 应用客户端)分别派生自 TcpServer
和 TcpClient
,它们是通用的 TCP 通信对象。
开始使用 TCP 应用服务器
- 将 NuGet 包
CodeArtEng.Tcp
安装到项目中。 - 创建
TcpAppServer
对象。 - (可选)定义连接时返回给客户端的欢迎消息。
- (可选)订阅
ClientConnected
和ClientDisconnected
事件。 - 启动服务器。
- 应用程序退出时应停止并释放服务器,以释放执行线程。
//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
对象将命令从插件组件注册到宿主应用程序。 - 确保
ExecutePluginCommand
和ShowHelp
方法调用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 日 - 首次发布