【发布时间】:2021-05-08 12:55:16
【问题描述】:
我需要你的帮助来计算 C# 中的校验和。下面的代码适用于用 C++ 编写的应用程序。应用程序正在接收来自 UDP 的数据包。这是接收和校验和计算的部分代码。
struct OPtoLSs {BlockReceivedS hdr; char data[0x100];}; //struct for received data
OPtoLSs mCKr;
#define hdrR mCKr.hdr.OPhdr
#define dataR mCKr.data
int const retHdr = recvfrom(sock, (char*)&hdrR, sizeof(hdrR), 0, (sockaddr*)(&from), &len);
int const retDat = recvfrom(sock, (char*)&dataR, hdrR.Length, 0, (sockaddr*)(&from), &len);
for(unsigned _int16 *p = (unsigned _int16*)&mCKr; p < (unsigned _int16*)&mCKr + ((retHdr+retDat)/2); p++)
{
ChkSum=(_int16)((*p+ChkSum)&0xffff);
}
assert_hard(ChkSum==0xffff);
我需要在 C# 中正确计算校验和。我使用了下面的代码,但是当我将任何消息从 C# 端发送到 C++ 端时,它会抛出这个error。请问有人可以在 C# 中帮助这个计算吗?感谢您的所有回复。
// mCKr.hdr.OPhdr equivalent
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Size = 12)]
public struct OPpacketHdrS
{
public UInt32 packetMark;
public UInt32 OPpacketID;
public UInt16 ChKSum
{
get
{
UInt16 accumulator = 0;
unsafe
{
fixed (OPpacketHdrS* x = &this)
{
for (UInt16* p = (UInt16*)x; p < x + 1; ++p)
{
accumulator += *p;
}
}
}
return accumulator;
}
}
public UInt16 Length;
}
// mCKr.data equivalent
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Size = 20)]
public struct CommandKeyS
{
public OPpacketHdrS OPhdr;
public mHdr Hdr; // Hdr.ID=CommandKeyR
[MarshalAs(UnmanagedType.U2)]
public UInt16 cmdKey, unused;
}
【问题讨论】:
-
如果每次都必须为 0xffff,那么校验和的价值是多少? (
assert_hard(ChkSum==0xffff);) -
如果我理解你的问题是正确的..然后在调试输出中我得到 36750..并且每个发送的 msg 这个数字都会增加一个
-
您的代码通过检查
(assert_hard(ChkSum==0xffff);要求校验和值为 0xffff。真正的价值似乎不同,你得到了这个断言。您确定发送的数据必须具有 0xffff 校验和吗?调试时,发送和接收的校验和的值是多少? -
错误弹出是因为它的校验和不是 0xffff,而大多数时候它不能是 0xffff。所以......我再次问:这个 assert_hard 是必需的吗?
-
要明确,这不是 C# 代码的错。应该是C++代码的问题。它可能会被错过,因为它大部分时间都在发布模式下运行。