【发布时间】:2018-12-05 00:29:19
【问题描述】:
一个 UDP 服务器和客户端正在运行,并且在编译或运行时没有显示任何错误,除非给它超过 20 个字符。然后突然我在服务器端只返回了 19 个字符。
看起来字符串的SizeConst 具有实际维度-1。
当我发送字符串时,它会一直工作,直到我得到一个超过 20 个字符的字符串。即使SizeConst = 20,它也只保留 19 个字符。 (当 3 时只有 2 个字符,等等。)
谁能解释一下为什么我突然丢失了一些数据?
/******************** STRUCT *****************************/
[StructLayout(LayoutKind.Sequential)]
public struct TEST
{
public string Buffer;
public int number;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public string aString;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] innerTestArray;
}
/****************** CLIENT ********************************//
static void Main(string[] args)
{
//Start ServerSide acknowledge
byte[] resp = Encoding.ASCII.GetBytes("INIT");
sendData(resp);
while (true)
{
TEST test = new TEST();
Console.WriteLine("");
Console.WriteLine("ReadLine : ");
test.aString = Console.ReadLine();
test.number = 10;
test.innerTestArray = null;
test.Buffer = null;
byte[] arr = structToBytes(test);
sendData(arr);
}
}
/**************** MARSHAL FUNCTIONS *************************/
static byte[] structToBytes(object str)
{
byte[] arr = new byte[Marshal.SizeOf(str)];
IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(str));
Marshal.StructureToPtr(str, pnt, false);
Marshal.Copy(pnt, arr, 0, Marshal.SizeOf(str));
Marshal.FreeHGlobal(pnt);
return arr;
}
static TEST structFromBytes(byte[] arr)
{
TEST str = new TEST();
int size = Marshal.SizeOf(str);
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(arr, 0, ptr, size);
str = (TEST)Marshal.PtrToStructure(ptr, str.GetType());
Marshal.FreeHGlobal(ptr);
return str;
}
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
在这个例子中,我为字符串分配了20 作为SizeConstant。但是当我收到字符串时,它有一个SizeOf(string) = 19。
此外,最好为字符串和其他数组提供更灵活的方法,以便具有更大的灵活性。 IE。不要在结构中使用SizeConst。在这个例子中,我只有一些小数据,但后来我要发送的数据有很大差异。结构和不同数据类型的列表和数组。
任何提示、技巧、想法?
PS:https://github.com/ritskes/C-UDP-struct-to-byte-DEMO-with-server-and-client的演示代码
【问题讨论】:
-
那个仓库是空的...
-
就我个人而言,我尽量避免任何涉及
Marshal的事情——它几乎总是没有必要或有助于理解正在发生的事情;Test这里是什么?我们能看到Test吗? -
您没有显示任何发送/接收代码;如果接收到的有效负载与您认为正在发送的有效负载不完全匹配,则其他任何操作都不起作用 - 所以首先要检查的是发送的内容与接收的内容。最简单的显示方法是
Console.WriteLine(BitConverter.ToString(yourByteArray))- 并比较十六进制转储 -
是的,尝试将两个存储库都上传到 github,但失败了。客户端已上传,可以找到。而且服务器现在似乎在另一个仓库中。 Github 对我来说是新的。它的行为与我预期的不同。但是现在有代码,但是在 2 个新的 repos 中。
-
进行编组的原因是,当 UDP 通过 byte[] 传递消息时,我可以将 STRUCT 直接发送到 byte[]。
标签: c# arrays struct udp marshalling