ControlRookie
返回文章

第19篇_源码加更 01|公共类型、配置和请求响应数据模型

公共类型决定整个协议栈能表达什么,GVL 常量决定它能承受多大的报文和多少连接。先公开这些文件,后续阅读 Parser、Server 和 Client 才有统一坐标。

公共类型决定整个协议栈能表达什么,GVL 常量决定它能承受多大的报文和多少连接。先公开这些文件,后续阅读 Parser、Server 和 Client 才有统一坐标。

适合谁收藏

  • 准备复用本组源码并审查对象边界的工程师。
  • 需要把公开代码装配进目标 CodeSys 工程的人。
  • 准备重新完成编译、离线测试和真机验证的读者。

本篇完整公开 5 个 ST 文件。代码直接读取已验证工程,保留声明、实现、注释和缩进;没有伪代码,没有跨文件拼接,也没有省略号。

先给结论

公共类型决定整个协议栈能表达什么,GVL 常量决定它能承受多大的报文和多少连接。先公开这些文件,后续阅读 Parser、Server 和 Client 才有统一坐标。 本篇的通过标准不是“代码已经贴出”,而是每个文件的职责、调用位置、状态边界和验证入口都能对应起来,并且完整代码可逐字回查源文件。

源码加更 01|公共类型、配置和请求响应数据模型
源码加更 01|公共类型、配置和请求响应数据模型

读图重点

先找到 E_HttpError 在本组中的位置,再沿图确认其余对象分别承担数据、状态、执行或诊断职责。图只给阅读顺序,最终判断必须回到下面的完整 ST 代码。

先看文件职责

序号文件职责行数
1E_HttpError.st协议栈统一错误枚举27
2E_HttpMethod.stHTTP 方法枚举16
3GVL_Http.st容量、超时和默认值常量25
4ST_HttpRequest.st结构化 HTTP 请求20
5ST_HttpResponse.st结构化 HTTP 响应17

阅读顺序不是按文件名机械展开。先看数据和状态,再看公开方法,最后顺着错误出口和调用对象检查边界。源码篇的目标是让读者能对照工程复现,不是用大段代码制造篇幅。

从协议约束到代码职责

协议约束

公共类型决定整个协议栈能表达什么,GVL 常量决定它能承受多大的报文和多少连接。先公开这些文件,后续阅读 Parser、Server 和 Client 才有统一坐标。 协议层只定义消息与状态成立的条件,工程层还必须把条件分配给确定对象,避免 Parser、Builder、Server、Client 和测试入口互相越权。

对象分工

  • 第 1 个对象 E_HttpError.st:承担“协议栈统一错误枚举”。阅读时先确认输入与公开输出,再追状态、长度和错误出口,最后核对它被谁周期调用或被哪个对象消费。
  • 第 2 个对象 E_HttpMethod.st:承担“HTTP 方法枚举”。阅读时先确认输入与公开输出,再追状态、长度和错误出口,最后核对它被谁周期调用或被哪个对象消费。
  • 第 3 个对象 GVL_Http.st:承担“容量、超时和默认值常量”。阅读时先确认输入与公开输出,再追状态、长度和错误出口,最后核对它被谁周期调用或被哪个对象消费。
  • 第 4 个对象 ST_HttpRequest.st:承担“结构化 HTTP 请求”。阅读时先确认输入与公开输出,再追状态、长度和错误出口,最后核对它被谁周期调用或被哪个对象消费。
  • 第 5 个对象 ST_HttpResponse.st:承担“结构化 HTTP 响应”。阅读时先确认输入与公开输出,再追状态、长度和错误出口,最后核对它被谁周期调用或被哪个对象消费。

装配与验证

这组文件必须作为一个职责单元阅读和编译。先用确定输入验证“资源边界必须显式”,再制造非法或容量边界验证“请求与响应使用结构体跨层传递”,最后在真实通信或上层调用中确认“错误枚举区分协议、容量和 TCP 故障”。如果单文件测试通过但装配后失败,应优先检查结构体、常量、状态枚举和周期调用关系,而不是立即重写核心算法。源码完整公开只证明读者拿到了同一事实源,目标运行时是否通过仍需重新编译和真机取证。

本篇从 E_HttpError.st 开始审查:先确认“资源边界必须显式”对应的类型、常量或公开输入,再沿 CASE 或方法调用追踪成功路径,随后逐个检查容量、超时和协议错误出口,最后在 ST_HttpResponse.st 对应的结果或装配位置确认错误能被观测、清理并再次执行。这个顺序专门用来区分“算法正确但没有周期调用”“状态能完成但错误被覆盖”和“错误枚举区分协议、容量和 TCP 故障尚未形成验证证据”三类问题。只有本篇源码、装配和验证使用同一组对象与同一组边界,完整开源才具有可复现意义。

本篇完整开源代码

下面按职责顺序给出本篇全部 ST 文件。每个代码块保留完整声明与实现;阅读时把状态、长度、错误出口和调用对象与上面的职责表逐项对照。

完整源码 1:E_HttpError.st

职责:协议栈统一错误枚举

iecst
/// 功能    : HTTP 协议栈错误枚举。
/// 库依赖 : 暂无
{attribute 'qualified_only'}
{attribute 'strict'}
TYPE E_HttpError :
(
    iNoError                       := 0,
    iNeedMoreData                  := 1,
    iInvalidArgument               := 2,
    iBufferTooSmall                := 3,
    iInvalidStartLine              := 10,
    iInvalidHeader                 := 11,
    iMissingHost                   := 12,
    iDuplicateHost                 := 13,
    iInvalidContentLength          := 14,
    iTransferEncodingContentLength := 15,
    iBodyTooLarge                  := 16,
    iChunkedDecodeFailed           := 17,
    iUnsupportedTransferEncoding   := 18,
    iTcpClientFailed               := 100,
    iTcpServerFailed               := 101,
    iTcpReadFailed                 := 102,
    iTcpWriteFailed                := 103,
    iTimeout                       := 104,
    iQueueFull                     := 105
) INT;
END_TYPE

完整源码 2:E_HttpMethod.st

职责:HTTP 方法枚举

iecst
/// 功能    : HTTP 方法枚举。
/// 库依赖 : 暂无
{attribute 'qualified_only'}
{attribute 'strict'}
TYPE E_HttpMethod :
(
    iUnknown := 0,
    iGet     := 1,
    iHead    := 2,
    iPost    := 3,
    iPut     := 4,
    iDelete  := 5,
    iPatch   := 6,
    iOptions := 7
) INT;
END_TYPE

完整源码 3:GVL_Http.st

职责:容量、超时和默认值常量

iecst
/// 功能    : HTTP 协议栈全局常量。
/// 库依赖 : 暂无
{attribute 'qualified_only'}
VAR_GLOBAL CONSTANT
    cnDefaultServerPort   : UINT := 8088;                  // 全局协议常量。
    cnMaxClientSlots      : UINT := 4;                     // 全局协议常量。
    cnRxBufferSize        : UINT := 4095;                  // 全局协议常量。
    cnTxBufferSize        : UINT := 4095;                  // 全局协议常量。
    cnMaxMessageSize      : UINT := 4095;                  // 全局协议常量。
    cnMaxHeaderSize       : UINT := 2047;                  // 全局协议常量。
    cnMaxBodySize         : UINT := 1023;                  // 全局协议常量。
    cnMaxTargetLen        : UINT := 255;                   // 全局协议常量。
    cnMaxHostLen          : UINT := 128;                   // 全局协议常量。
    cnMaxHeaderValueLen   : UINT := 255;                   // 全局协议常量。
    cnMaxChunkLineLen     : UINT := 32;                    // 全局协议常量。
    cnTcpConnectTimeoutUs : UDINT := 5000000;              // 全局协议常量。
    cnClientTimeoutMs     : UDINT := 8000;                 // 全局协议常量。
    cnServerConnectionMs  : UDINT := 8000;                 // 全局协议常量。
    cnWriteTimeout        : TIME := T#5S;                  // 全局协议常量。
    cnTcpReadChunkSize    : UINT := 240;                   // NBS 单次 TCP_Read 字节数,避开部分运行时 255 字节边界。
    cnTcpWriteChunkSize   : UINT := 240;                   // NBS 单次 TCP_Write 字节数,大响应按 TCP 字节流分批发送。
    cnTcpReadMaxErrorCount: UINT := 3;                     // TCP_Read 连续错误滤波次数,避免大报文半包接收被瞬时读错误误杀。
    cnDefaultContentType  : STRING(32) := 'text/plain';    // 全局协议常量。
    cnDefaultPath         : STRING(8) := '/';              // 全局协议常量。
END_VAR

完整源码 4:ST_HttpRequest.st

职责:结构化 HTTP 请求

iecst
/// 功能    : HTTP 请求结构。
/// 库依赖 : 暂无
TYPE ST_HttpRequest :
STRUCT
    eMethod           : E_HttpMethod := E_HttpMethod.iUnknown;
    sMethod           : STRING(16) := '';
    sTarget           : STRING(GVL_Http.cnMaxTargetLen) := '';
    sVersion          : STRING(16) := 'HTTP/1.1';
    sHost             : STRING(GVL_Http.cnMaxHostLen) := '';
    sContentType      : STRING(96) := '';
    sAuthorization    : STRING(160) := '';
    sAdditionalHeader : STRING(GVL_Http.cnMaxHeaderSize) := '';
    sRawHeaders       : STRING(GVL_Http.cnMaxHeaderSize) := '';
    sBody             : STRING(GVL_Http.cnMaxBodySize) := '';
    bHasContentLength : BOOL := FALSE;
    bTransferChunked  : BOOL := FALSE;
    bConnectionClose  : BOOL := FALSE;
    udiContentLength  : UDINT := 0;
END_STRUCT
END_TYPE

完整源码 5:ST_HttpResponse.st

职责:结构化 HTTP 响应

iecst
/// 功能    : HTTP 响应结构。
/// 库依赖 : 暂无
TYPE ST_HttpResponse :
STRUCT
    sVersion          : STRING(16) := 'HTTP/1.1';
    uiStatusCode      : UINT := 0;
    sReason           : STRING(64) := '';
    sContentType      : STRING(96) := 'text/plain';
    sAdditionalHeader : STRING(GVL_Http.cnMaxHeaderSize) := '';
    sRawHeaders       : STRING(GVL_Http.cnMaxHeaderSize) := '';
    sBody             : STRING(GVL_Http.cnMaxBodySize) := '';
    bHasContentLength : BOOL := FALSE;
    bTransferChunked  : BOOL := FALSE;
    bConnectionClose  : BOOL := FALSE;
    udiContentLength  : UDINT := 0;
END_STRUCT
END_TYPE

本篇阅读抓手

  • 资源边界必须显式。
  • 请求与响应使用结构体跨层传递。
  • 错误枚举区分协议、容量和 TCP 故障。

如何验证这组源码

  1. 先针对 E_HttpError.st 的公开输入和错误出口建立确定性用例。
  2. 再把“资源边界必须显式”转成至少一个正常场景和一个失败场景。
  3. 本篇 5 个文件必须一起编译,避免只验证单个函数而漏掉数据结构或调用边界。
  4. 真机复核时重点观察“错误枚举区分协议、容量和 TCP 故障”,并保留对应状态、计数和原始报文。

这一篇你最该记住

  • 资源边界必须显式。
  • 请求与响应使用结构体跨层传递。
  • 错误枚举区分协议、容量和 TCP 故障。

系列导航

  • 系列:CodeSys HTTP 系列教程,第 19/28 篇。
  • 当前源码加更:第 1/8 篇。
  • 本篇完整源码文件数:5。
  • 上一篇:第18篇
  • 下一篇:第20篇
评论和回复区

评论区预留

这里先保留评论和回复结构,不接入第三方服务。后续统一决定登录、匿名、审核、反垃圾和静态站兼容策略。

↑ ↓