适合谁收藏准备复用本组源码并审查对象边界的工程师。需要把公开代码装配进目标 CodeSys 工程的人。准备重新完成编译、离线测试和真机验证的读者。开源范围本篇完整公开 5 个 ST 文件。代码直接读取已验证工程保留声明、实现、注释和缩进没有伪代码没有跨文件拼接也没有省略号。先给结论公共类型决定整个协议栈能表达什么GVL 常量决定它能承受多大的报文和多少连接。先公开这些文件后续阅读 Parser、Server 和 Client 才有统一坐标。 本篇的通过标准不是“代码已经贴出”而是每个文件的职责、调用位置、状态边界和验证入口都能对应起来并且完整代码可逐字回查源文件。读图重点先找到E_HttpError在本组中的位置再沿图确认其余对象分别承担数据、状态、执行或诊断职责。图只给阅读顺序最终判断必须回到下面的完整 ST 代码。先看文件职责序号文件职责行数1E_HttpError.st协议栈统一错误枚举272E_HttpMethod.stHTTP 方法枚举163GVL_Http.st容量、超时和默认值常量254ST_HttpRequest.st结构化 HTTP 请求205ST_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 文件。每个代码块保留完整声明与实现阅读时把状态、长度、错误出口和调用对象与上面的职责表逐项对照。完整源码 1E_HttpError.st职责协议栈统一错误枚举/// 功能 : 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完整源码 2E_HttpMethod.st职责HTTP 方法枚举/// 功能 : 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完整源码 3GVL_Http.st职责容量、超时和默认值常量/// 功能 : 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完整源码 4ST_HttpRequest.st职责结构化 HTTP 请求/// 功能 : 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完整源码 5ST_HttpResponse.st职责结构化 HTTP 响应/// 功能 : 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 故障。如何验证这组源码先针对E_HttpError.st的公开输入和错误出口建立确定性用例。再把“资源边界必须显式”转成至少一个正常场景和一个失败场景。本篇 5 个文件必须一起编译避免只验证单个函数而漏掉数据结构或调用边界。真机复核时重点观察“错误枚举区分协议、容量和 TCP 故障”并保留对应状态、计数和原始报文。这一篇你最该记住资源边界必须显式。请求与响应使用结构体跨层传递。错误枚举区分协议、容量和 TCP 故障。系列导航系列CodeSys HTTP 系列教程第 19/28 篇。当前源码加更第 1/8 篇。本篇完整源码文件数5。上一篇第18篇下一篇第20篇