OPC报文详解
OPC (OLE for Process Control) 是一种工业通讯协议的标准,用于实现不同制造商的设备和系统之间的数据交换。它主要用于工业自动化系统中。OPC标准有几个不同的规范,包括OPC DA (Data Access)、OPC UA (Unified Architecture)、OPC HDA (Historical Data Access) 等。
本文主要介绍 OPC UA over TCP、OPC UA Secure Conversation的报文格式。
1. OPC Classic (包括OPC DA, OPC HDA等)
OPC Classic是基于Microsoft的COM/DCOM(组件对象模型/分布式组件对象模型)技术,因此它并没有一个类似于TCP/IP的统一、标准化的“报文格式”。
在OPC Classic中,数据交换和通信是通过COM/DCOM机制实现的,这意味着数据是以COM对象的形式进行传输的,而不是通过某种特定的、固定格式的报文。
2.OPC UA (Unified Architecture)
OPC UA是一种更现代的协议,设计用来取代OPC Classic,提供更加安全、跨平台的数据交换机制。OPC UA定义了一套详细的服务和信息模型,使得它可以用于不同的传输层,比如TCP、HTTP等。
OPC UA通信模型中,客户端和服务器之间的交互是基于一系列的服务请求和响应。每个服务请求和响应都遵循OPC UA定义的编码规则,可以序列化为二进制流或者XML。
常见的OPC UA报文主要分为两类 OPC UA over TCP、OPC UA Secure Conversation
2.1 OPC UA over TCP报文结构
OPC UA over TCP报文包括消息头和消息体,主要结构如下:
用途 | 消息头 | 消息体 |
---|---|---|
长度 | 8byte | 不定 |
描述 | 控制和描述报文 | 实际要传输的数据,其内容和结构取决于具体的OPC UA服务请求或响应 |
2.1.1消息头
其中,消息头部分报文结构如下:
用途 | 消息类型 | 保留段 | 消息大小 |
---|---|---|---|
长度 | 3byte | 1byte | 4byte |
描述 | 用于标识报文类型 | 如果消息类型是OPC UA链接协议支持的值之一,则设置为“F”的ACSII码 | 整个消息头+消息体的长度,单位为字节 |
消息类型部分共分四类:
- HEL:表示消息体为Hello报文
- ACK:表示消息体为Acknowledge报文
- ERR:表示消息体为Error报文
- RHE:表示消息体为ReverseHello报文
2.1.2 消息体
2.1.2.1 Hello报文
当消息类型为HEL时,代表消息体部分为一个Hello报文,具体格式如下:
用途 | 长度 | 描述 |
---|---|---|
协议版本号 | 4byte | 这个字段指示发送方使用的OPC UA规范的版本。接收方可以用这个信息来判断是否能够理解接收到的报文。 |
接收缓冲区大小 | 4byte | 指定了接收方准备为此连接分配的最大消息大小。它用于流控制和避免接收方被过大的消息所淹没。单位为字节,该值必须大于8192。 |
发送缓冲区大小 | 4byte | 发送缓冲区大小。这个字段指定了发送方准备为此连接使用的最大消息大小。这也是流控制的一部分,确保双方都能处理交换的数据。单位为字节,该值必须大于8192。 |
最大消息大小 | 4byte | 这个字段指定了双方允许的最大消息体的大小。它用于防止因处理过大的单个消息而导致的性能问题。0表示客户端不限制。 |
最大分块数量 | 4byte | 这个字段指定了应答报文可以被分割成的最大块数。这有助于管理大量数据的传输,确保即使是大消息也可以在双方之间有效地传输。0表示客户端不限制。 |
终端URL | 最大4096byte | 客户端希望连接到的终端的URL。 如果长度超过4096 或无法识别URL所标识的资源,服务器应返回Bad_TcpEndpointUrlInvalid错误消息并关闭连接。 |
Hello报文是OPC UA TCP协议握手过程的一个重要部分,通过它,客户端和服务器可以交换基本的通信参数,为后续的更复杂交互建立基础。
2.1.2.2Acknowledge报文
用途 | 长度 | 描述 |
---|---|---|
协议版本号 | 4byte | 服务端支持的OPC UA协议的版本 |
接收缓冲区大小 | 4byte | 指定了接收方准备为此连接分配的最大消息大小。它用于流控制和避免接收方被过大的消息所淹没。单位为字节,该值必须大于8192。 |
发送缓冲区大小 | 4byte | 发送缓冲区大小。这个字段指定了发送方准备为此连接使用的最大消息大小。这也是流控制的一部分,确保双方都能处理交换的数据。单位为字节,该值必须大于8192。 |
最大消息大小 | 4byte | 这个字段指定了双方允许的最大消息体的大小。它用于防止因处理过大的单个消息而导致的性能问题。0表示客户端不限制。 |
最大分块数量 | 4byte | 这个字段指定了应答报文可以被分割成的最大块数。这有助于管理大量数据的传输,确保即使是大消息也可以在双方之间有效地传输。0表示客户端不限制。 |
Acknowledge报文提供了客户端和服务器之间通信所需的基本参数,确保双方能够有效地交换后续的OPC UA消息。客户端在收到Acknowledge报文后,会根据提供的参数调整自己的通信设置,随后双方可以开始正式的数据交换。
2.1.2.3 Error报文
用途 | 长度 | 描述 |
---|---|---|
错误码 | 4byte | 错误的数字代码。 |
原因 | 最大4096byte | 错误的详细描述。 |
错误码会随着版本更新而更新,这里提供一份当前版本(UA-1.05.03-2023-12-15)的错误码列表,具体可以参看官方github
错误名 | 错误码 |
---|---|
Good | 0x00000000 |
Uncertain | 0x40000000 |
Bad | 0x80000000 |
BadUnexpectedError | 0x80010000 |
BadInternalError | 0x80020000 |
BadOutOfMemory | 0x80030000 |
BadResourceUnavailable | 0x80040000 |
BadCommunicationError | 0x80050000 |
BadEncodingError | 0x80060000 |
BadDecodingError | 0x80070000 |
BadEncodingLimitsExceeded | 0x80080000 |
BadRequestTooLarge | 0x80B80000 |
BadResponseTooLarge | 0x80B90000 |
BadUnknownResponse | 0x80090000 |
BadTimeout | 0x800A0000 |
BadServiceUnsupported | 0x800B0000 |
BadShutdown | 0x800C0000 |
BadServerNotConnected | 0x800D0000 |
BadServerHalted | 0x800E0000 |
BadNothingToDo | 0x800F0000 |
BadTooManyOperations | 0x80100000 |
BadTooManyMonitoredItems | 0x80DB0000 |
BadDataTypeIdUnknown | 0x80110000 |
BadCertificateInvalid | 0x80120000 |
BadSecurityChecksFailed | 0x80130000 |
BadCertificatePolicyCheckFailed | 0x81140000 |
BadCertificateTimeInvalid | 0x80140000 |
BadCertificateIssuerTimeInvalid | 0x80150000 |
BadCertificateHostNameInvalid | 0x80160000 |
BadCertificateUriInvalid | 0x80170000 |
BadCertificateUseNotAllowed | 0x80180000 |
BadCertificateIssuerUseNotAllowed | 0x80190000 |
BadCertificateUntrusted | 0x801A0000 |
BadCertificateRevocationUnknown | 0x801B0000 |
BadCertificateIssuerRevocationUnknown | 0x801C0000 |
BadCertificateRevoked | 0x801D0000 |
BadCertificateIssuerRevoked | 0x801E0000 |
BadCertificateChainIncomplete | 0x810D0000 |
BadUserAccessDenied | 0x801F0000 |
BadIdentityTokenInvalid | 0x80200000 |
BadIdentityTokenRejected | 0x80210000 |
BadSecureChannelIdInvalid | 0x80220000 |
BadInvalidTimestamp | 0x80230000 |
BadNonceInvalid | 0x80240000 |
BadSessionIdInvalid | 0x80250000 |
BadSessionClosed | 0x80260000 |
BadSessionNotActivated | 0x80270000 |
BadSubscriptionIdInvalid | 0x80280000 |
BadRequestHeaderInvalid | 0x802A0000 |
BadTimestampsToReturnInvalid | 0x802B0000 |
BadRequestCancelledByClient | 0x802C0000 |
BadTooManyArguments | 0x80E50000 |
BadLicenseExpired | 0x810E0000 |
BadLicenseLimitsExceeded | 0x810F0000 |
BadLicenseNotAvailable | 0x81100000 |
BadServerTooBusy | 0x80EE0000 |
GoodPasswordChangeRequired | 0x00EF0000 |
GoodSubscriptionTransferred | 0x002D0000 |
GoodCompletesAsynchronously | 0x002E0000 |
GoodOverload | 0x002F0000 |
GoodClamped | 0x00300000 |
BadNoCommunication | 0x80310000 |
BadWaitingForInitialData | 0x80320000 |
BadNodeIdInvalid | 0x80330000 |
BadNodeIdUnknown | 0x80340000 |
BadAttributeIdInvalid | 0x80350000 |
BadIndexRangeInvalid | 0x80360000 |
BadIndexRangeNoData | 0x80370000 |
BadIndexRangeDataMismatch | 0x80EA0000 |
BadDataEncodingInvalid | 0x80380000 |
BadDataEncodingUnsupported | 0x80390000 |
BadNotReadable | 0x803A0000 |
BadNotWritable | 0x803B0000 |
BadOutOfRange | 0x803C0000 |
BadNotSupported | 0x803D0000 |
BadNotFound | 0x803E0000 |
BadObjectDeleted | 0x803F0000 |
BadNotImplemented | 0x80400000 |
BadMonitoringModeInvalid | 0x80410000 |
BadMonitoredItemIdInvalid | 0x80420000 |
BadMonitoredItemFilterInvalid | 0x80430000 |
BadMonitoredItemFilterUnsupported | 0x80440000 |
BadFilterNotAllowed | 0x80450000 |
BadStructureMissing | 0x80460000 |
BadEventFilterInvalid | 0x80470000 |
BadContentFilterInvalid | 0x80480000 |
BadFilterOperatorInvalid | 0x80C10000 |
BadFilterOperatorUnsupported | 0x80C20000 |
BadFilterOperandCountMismatch | 0x80C30000 |
BadFilterOperandInvalid | 0x80490000 |
BadFilterElementInvalid | 0x80C40000 |
BadFilterLiteralInvalid | 0x80C50000 |
BadContinuationPointInvalid | 0x804A0000 |
BadNoContinuationPoints | 0x804B0000 |
BadReferenceTypeIdInvalid | 0x804C0000 |
BadBrowseDirectionInvalid | 0x804D0000 |
BadNodeNotInView | 0x804E0000 |
BadNumericOverflow | 0x81120000 |
BadLocaleNotSupported | 0x80ED0000 |
BadNoValue | 0x80F00000 |
BadServerUriInvalid | 0x804F0000 |
BadServerNameMissing | 0x80500000 |
BadDiscoveryUrlMissing | 0x80510000 |
BadSempahoreFileMissing | 0x80520000 |
BadRequestTypeInvalid | 0x80530000 |
BadSecurityModeRejected | 0x80540000 |
BadSecurityPolicyRejected | 0x80550000 |
BadTooManySessions | 0x80560000 |
BadUserSignatureInvalid | 0x80570000 |
BadApplicationSignatureInvalid | 0x80580000 |
BadNoValidCertificates | 0x80590000 |
BadIdentityChangeNotSupported | 0x80C60000 |
BadRequestCancelledByRequest | 0x805A0000 |
BadParentNodeIdInvalid | 0x805B0000 |
BadReferenceNotAllowed | 0x805C0000 |
BadNodeIdRejected | 0x805D0000 |
BadNodeIdExists | 0x805E0000 |
BadNodeClassInvalid | 0x805F0000 |
BadBrowseNameInvalid | 0x80600000 |
BadBrowseNameDuplicated | 0x80610000 |
BadNodeAttributesInvalid | 0x80620000 |
BadTypeDefinitionInvalid | 0x80630000 |
BadSourceNodeIdInvalid | 0x80640000 |
BadTargetNodeIdInvalid | 0x80650000 |
BadDuplicateReferenceNotAllowed | 0x80660000 |
BadInvalidSelfReference | 0x80670000 |
BadReferenceLocalOnly | 0x80680000 |
BadNoDeleteRights | 0x80690000 |
UncertainReferenceNotDeleted | 0x40BC0000 |
BadServerIndexInvalid | 0x806A0000 |
BadViewIdUnknown | 0x806B0000 |
BadViewTimestampInvalid | 0x80C90000 |
BadViewParameterMismatch | 0x80CA0000 |
BadViewVersionInvalid | 0x80CB0000 |
UncertainNotAllNodesAvailable | 0x40C00000 |
GoodResultsMayBeIncomplete | 0x00BA0000 |
BadNotTypeDefinition | 0x80C80000 |
UncertainReferenceOutOfServer | 0x406C0000 |
BadTooManyMatches | 0x806D0000 |
BadQueryTooComplex | 0x806E0000 |
BadNoMatch | 0x806F0000 |
BadMaxAgeInvalid | 0x80700000 |
BadSecurityModeInsufficient | 0x80E60000 |
BadHistoryOperationInvalid | 0x80710000 |
BadHistoryOperationUnsupported | 0x80720000 |
BadInvalidTimestampArgument | 0x80BD0000 |
BadWriteNotSupported | 0x80730000 |
BadTypeMismatch | 0x80740000 |
BadMethodInvalid | 0x80750000 |
BadArgumentsMissing | 0x80760000 |
BadNotExecutable | 0x81110000 |
BadTooManySubscriptions | 0x80770000 |
BadTooManyPublishRequests | 0x80780000 |
BadNoSubscription | 0x80790000 |
BadSequenceNumberUnknown | 0x807A0000 |
GoodRetransmissionQueueNotSupported | 0x00DF0000 |
BadMessageNotAvailable | 0x807B0000 |
BadInsufficientClientProfile | 0x807C0000 |
BadStateNotActive | 0x80BF0000 |
BadAlreadyExists | 0x81150000 |
BadTcpServerTooBusy | 0x807D0000 |
BadTcpMessageTypeInvalid | 0x807E0000 |
BadTcpSecureChannelUnknown | 0x807F0000 |
BadTcpMessageTooLarge | 0x80800000 |
BadTcpNotEnoughResources | 0x80810000 |
BadTcpInternalError | 0x80820000 |
BadTcpEndpointUrlInvalid | 0x80830000 |
BadRequestInterrupted | 0x80840000 |
BadRequestTimeout | 0x80850000 |
BadSecureChannelClosed | 0x80860000 |
BadSecureChannelTokenUnknown | 0x80870000 |
BadSequenceNumberInvalid | 0x80880000 |
BadProtocolVersionUnsupported | 0x80BE0000 |
BadConfigurationError | 0x80890000 |
BadNotConnected | 0x808A0000 |
BadDeviceFailure | 0x808B0000 |
BadSensorFailure | 0x808C0000 |
BadOutOfService | 0x808D0000 |
BadDeadbandFilterInvalid | 0x808E0000 |
UncertainNoCommunicationLastUsableValue | 0x408F0000 |
UncertainLastUsableValue | 0x40900000 |
UncertainSubstituteValue | 0x40910000 |
UncertainInitialValue | 0x40920000 |
UncertainSensorNotAccurate | 0x40930000 |
UncertainEngineeringUnitsExceeded | 0x40940000 |
UncertainSubNormal | 0x40950000 |
GoodLocalOverride | 0x00960000 |
GoodSubNormal | 0x00EB0000 |
BadRefreshInProgress | 0x80970000 |
BadConditionAlreadyDisabled | 0x80980000 |
BadConditionAlreadyEnabled | 0x80CC0000 |
BadConditionDisabled | 0x80990000 |
BadEventIdUnknown | 0x809A0000 |
BadEventNotAcknowledgeable | 0x80BB0000 |
BadDialogNotActive | 0x80CD0000 |
BadDialogResponseInvalid | 0x80CE0000 |
BadConditionBranchAlreadyAcked | 0x80CF0000 |
BadConditionBranchAlreadyConfirmed | 0x80D00000 |
BadConditionAlreadyShelved | 0x80D10000 |
BadConditionNotShelved | 0x80D20000 |
BadShelvingTimeOutOfRange | 0x80D30000 |
BadNoData | 0x809B0000 |
BadBoundNotFound | 0x80D70000 |
BadBoundNotSupported | 0x80D80000 |
BadDataLost | 0x809D0000 |
BadDataUnavailable | 0x809E0000 |
BadEntryExists | 0x809F0000 |
BadNoEntryExists | 0x80A00000 |
BadTimestampNotSupported | 0x80A10000 |
GoodEntryInserted | 0x00A20000 |
GoodEntryReplaced | 0x00A30000 |
UncertainDataSubNormal | 0x40A40000 |
GoodNoData | 0x00A50000 |
GoodMoreData | 0x00A60000 |
BadAggregateListMismatch | 0x80D40000 |
BadAggregateNotSupported | 0x80D50000 |
BadAggregateInvalidInputs | 0x80D60000 |
BadAggregateConfigurationRejected | 0x80DA0000 |
GoodDataIgnored | 0x00D90000 |
BadRequestNotAllowed | 0x80E40000 |
BadRequestNotComplete | 0x81130000 |
BadTransactionPending | 0x80E80000 |
BadTicketRequired | 0x811F0000 |
BadTicketInvalid | 0x81200000 |
BadLocked | 0x80E90000 |
BadRequiresLock | 0x80EC0000 |
GoodEdited | 0x00DC0000 |
GoodPostActionFailed | 0x00DD0000 |
UncertainDominantValueChanged | 0x40DE0000 |
GoodDependentValueChanged | 0x00E00000 |
BadDominantValueChanged | 0x80E10000 |
UncertainDependentValueChanged | 0x40E20000 |
BadDependentValueChanged | 0x80E30000 |
GoodEdited_DependentValueChanged | 0x01160000 |
GoodEdited_DominantValueChanged | 0x01170000 |
GoodEdited_DominantValueChanged_DependentValueChanged | 0x01180000 |
BadEdited_OutOfRange | 0x81190000 |
BadInitialValue_OutOfRange | 0x811A0000 |
BadOutOfRange_DominantValueChanged | 0x811B0000 |
BadEdited_OutOfRange_DominantValueChanged | 0x811C0000 |
BadOutOfRange_DominantValueChanged_DependentValueChanged | 0x811D0000 |
BadEdited_OutOfRange_DominantValueChanged_DependentValueChanged | 0x811E0000 |
GoodCommunicationEvent | 0x00A70000 |
GoodShutdownEvent | 0x00A80000 |
GoodCallAgain | 0x00A90000 |
GoodNonCriticalTimeout | 0x00AA0000 |
BadInvalidArgument | 0x80AB0000 |
BadConnectionRejected | 0x80AC0000 |
BadDisconnect | 0x80AD0000 |
BadConnectionClosed | 0x80AE0000 |
BadInvalidState | 0x80AF0000 |
BadEndOfStream | 0x80B00000 |
BadNoDataAvailable | 0x80B10000 |
BadWaitingForResponse | 0x80B20000 |
BadOperationAbandoned | 0x80B30000 |
BadExpectedStreamToBlock | 0x80B40000 |
BadWouldBlock | 0x80B50000 |
BadSyntaxError | 0x80B60000 |
BadMaxConnectionsReached | 0x80B70000 |
UncertainTransducerInManual | 0x42080000 |
UncertainSimulatedValue | 0x42090000 |
UncertainSensorCalibration | 0x420A0000 |
UncertainConfigurationError | 0x420F0000 |
GoodCascadeInitializationAcknowledged | 0x04010000 |
GoodCascadeInitializationRequest | 0x04020000 |
GoodCascadeNotInvited | 0x04030000 |
GoodCascadeNotSelected | 0x04040000 |
GoodFaultStateActive | 0x04070000 |
GoodInitiateFaultState | 0x04080000 |
GoodCascade | 0x04090000 |
BadDataSetIdInvalid | 0x80E70000 |
2.1.2.4ReverseHello报文
用途 | 长度 | 描述 |
---|---|---|
服务器URI | 最大4096byte | 发送消息的服务器的ApplicationUri。 |
终端URL | 最大4096byte | 客户端在建立SecureChannel时使用的端点的URL |
对于基于连接的协议,如TCP,ReverseHello消息允许防火墙后面的服务器没有打开端口连接到客户端,并请求客户端使用服务器创建的套接字建立SecureChannel。
对于基于消息的协议,ReverseHello消息允许服务器向客户端通告它们的存在。在这种情况下,终端URL指定服务器的特定地址和访问它所需的任何令牌。
2.2 OPC UA Secure Conversation报文结构
OPC UA Secure Conversation(OPC UA 安全会话)的报文格式设计用于在客户端与服务器之间建立和维护一个加密和签名的通信通道。
用途 | 消息头 | 安全头 | 序列头 | 载荷 | 安全脚 |
---|---|---|---|---|---|
长度 | 12byte | 不定 | 8byte | 不定 | 不定 |
描述 | 控制和描述报文 | 包含安全相关的信息。根据对称、不对称安全算法有不同长度 | 包括序列号和请求ID | 这是实际的应用数据部分,根据安全头中定义的安全策略,它可能被加密和/或签名。 | (可选)如果报文被签名,这部分包含签名。不是所有的安全策略都需要签名。 |
2.2.1 消息头
用途 | 消息类型 | 是否终结 | 消息大小 | 安全通道ID |
---|---|---|---|---|
长度 | 3byte | 1byte | 4byte | 4byte |
描述 | 用于标识报文类型 | 一个字节的ASCII代码,指示是否是消息中的最后一个块。 | 从消息头开始的长度,单位为字节 | 服务器分配的SecureChannel的唯一标识符 |
2.2.1.1 消息类型
消息类型主要有三种:
- MSG 使用与通道有关的密钥加密的消息
- OPN 打开安全通道消息
- CLO 关闭安全通道消息
2.2.1.2 是否终结
一个字节的ASCII代码,指示MessageChunk是否是消息中的最后一个块。
定义为以下值:
- C 中间块。
- F 最后一个块。
- A 最后一个块(当发生错误并且消息被中止时使用)。
此字段仅对消息类型是MSG有意义,对于其他消息类型,此字段始终为“F”。
2.2.1.3 消息大小
从消息头开始的长度,单位为字节
2.2.1.4 安全通道ID
服务器分配的SecureChannel的唯一标识符,如果服务器接收到无法识别的安全用户ID,则应返回相应的传输层错误。
2.2.2 安全头
定义了消息应用了哪些加密操作,有两个版本:非对称算法安全头和对称算法安全头。
2.2.2.1 非对称算法安全头
用途 | 长度 | 描述 |
---|---|---|
安全策略URI长度 | 4byte | 安全策略URI的长度。如果未指定URI,则此值可能为0或-1。其他负值无效。单位为字节。 |
安全策略URI | 不定 | 用于保护消息的安全策略的URI。此字段编码为不带空结束符的UTF-8字符串。 |
发送方证书长度 | 4byte | 发送方证书的长度。如果未指定证书,则此值可能为0或-1。其他负值无效。单位为字节。 |
发送方证书 | 不定 | 发送方证书 |
接收方证书指纹长度 | 4byte | 接收方证书指纹的长度,如果已加密,则此字段的值为20。如果未加密,则值可以是0或-1。单位为字节。 |
接收方证书指纹 | 不定 | 接收方证书指纹。如果消息未加密,则此字段应为空。 |
2.2.2.2对称算法安全头
用途 | 长度 | 描述 |
---|---|---|
令牌ID | 4byte | 用于保护消息的安全通道安全令牌的唯一标识符。如果服务器接收到它无法识别的令牌ID,它将返回相应的传输层错误。 |
2.2.3 序列头
用途 | 长度 | 描述 |
---|---|---|
序列号 | 4byte | 由发送方分配的单调递增序列号。 |
请求ID | 4byte | 由客户端分配给OPC UA请求消息的标识符。请求和相关响应的所有消息都使用相同的标识符。 |
2.2.4 载荷
这是报文的主体部分,包含了实际的操作请求或响应数据。载荷的大小是可变的,取决于实际传输的数据量。
2.2.5 安全脚
这部分是可选的,仅在使用某些特定的安全策略时才存在。它包含了额外的安全信息,比如填充数据和签名。安全脚大小同样是可变的,取决于使用的安全策略和数据。
OPC报文详解的更多相关文章
- HTTP权威指南读书笔记(一)HTTP概述、URL和资源及报文详解
一.HTTP概述 1.WEB客户端和服务器. 2.资源:资源可以是各种格式的静态文件,也可以是应用程序. 3.媒体类型 4.URI:统一资源标识符 URL:统一资源定位符. URL的第一部分称为方案: ...
- http协议之报文详解
一. 概述 用于HTTP协议交互的信息被称为HTTP报文.请求端(客户端)的http报文叫做请求报文,响应端的叫做响应报文. 报文,是网络中交换和传输的数据单元,即站点一次性要发送的数据块.报文包含了 ...
- HTTP/1.1报文详解
本文为<三万长文50+趣图带你领悟web编程的内功心法>第三个章节. 3.HTTP/1.1报文详解 在RFC2616中心详细的描述了HTTP/1.1[1]的报文,感兴趣的朋友也可以前往阅读 ...
- 应用层(一)HTTP服务访问基本流程和HTTP报文详解
HTTP属于TCP/IP模型中一个面向文本的应用层协议,所使用的服务器端口号的TCP中的80端口,通信双方在这个基础上进行通信. 每个服务器都有一个应用进程,时刻监听着80端口的用户访问请求.当有用户 ...
- HTTP请求与响应报文详解
如图所示,这是客户端往服务器发送请求时的报文: 一般来说,将报文分成三个部分,请求行.请求头.请求体 如图,请求行包括三部分内容 1.请求方法,在HTTP里的请求方法种类较多,但就移动端开发来说,常用 ...
- ModbusRtu通信报文详解【二】
这里接着上一篇内容对ModbusRtu的通信报文做个详细描述: [1]强制单个线圈 功能码:05H [2]预置单个寄存器 功能码:06H [3]强制多个线圈 功能码;0FH [4]预置多个寄存器 功能 ...
- ModbusRtu通信报文详解【一】
Modbus协议可谓是工业控制领域应用最广泛的协议之一.根据不同的电气接口,包括Modbus Rtu/ASCII,Modbus TCP/UDP,从学习的角度来说,只要学会其中一种,剩余的都是大同小异的 ...
- HTTP报文详解
二.HTTP请求首部字段 1 Accept 2 Accept-Charset 3 Accept-Encoding 4 Accept-Language 5 Authorization 6
- ModbusTCP报文详解【二】
[1]功能码05H [2]功能码06H [3]功能码0FH [4]功能码10H
- ModbusTCP报文详解【一】
[1]功能码01H [2]功能码02H [3]功能码03H [4]功能码04H
随机推荐
- Java并发编程实例--1.创建和运行一个线程
从这一篇开始写Java并发编程实例,内容都翻译整理自书籍:<Java 7 Concurrency Cookbook> 谈到线程,无法逃避的一个问题就是: 并发(concurrency)和并 ...
- beego中数据库表创建
package main import ( "fmt" "github.com/astaxie/beego/orm" _ "github.com/go ...
- 在本地运行 LLMs 的 6 种方法
商业人工智能和大型语言模型 (LLM) 有一个很大的缺点:隐私.在处理敏感数据或专有数据时,我们无法从这些工具中获益.因此,我们需要了解如何在本地运行私人 LLM.开源模型提供了一种解决方案,但它们也 ...
- 【Azure 事件中心】Event Hubs中存在非常多的错误数据,是否能提前删除这些数据呢?
问题描述 因为一些特殊原因,Event Hub 里面堆积了很多不需要的数据事件,正常要等事件中的过期时间到后才有Event Hub自动删除掉,但希望能够尽快马上删除,有没有什么手动的方法吗? 问题解答 ...
- 【Azure Redis 缓存】Azure Cache for Redis有默认备份可以用于恢复么?
问题描述 Azure Cache for Redis有默认备份可以用于恢复么? 答: 只有高级版Redis有. 问题原因 Azure Cache for Redis有不同的版本定价层(基本 Basic ...
- 别再低效筛选数据了!试试pandas query函数
数据过滤在数据分析过程中具有极其重要的地位,因为在真实世界的数据集中,往往存在重复.缺失或异常的数据.pandas提供的数据过滤功能可以帮助我们轻松地识别和处理这些问题数据,从而确保数据的质量和准确性 ...
- Linux性能监控(一)-sar
sar是一个非常全面的一个分析工具,对文件的读写,系统调用的使用情况,磁盘IO,CPU相关使用情况,内存使用情况,进程活动等都可以进行有效的分析.sar工具将对系统当前的状态进行取样,然后通过计算数据 ...
- [VueJsDev] 基础知识 - Button的全局节流
[VueJsDev] 目录列表 https://www.cnblogs.com/pengchenggang/p/17037320.html Button的全局节流 ::: details 目录 目录 ...
- coast 海岸 单词记忆方法
coast 海岸 单词记忆方法 coa 扣 想象一个碗扣下去 st站 碗的边和地面的接触面 就是海岸的边 coast 逼近的地方-海岸 coast (n.) - "margin of the ...
- 在运行程序是出现sh: 行 1: cls: 未找到命令
在运行程序是出现sh: 行 1: cls: 未找到命令 原因是system("cls");--这是在程序中调用系统命令,但是linux识别不了.功能是清除当前的终端显示数据.找到l ...