C#中的Struct.Pack等效

我正在构建一个连接到渲染应用程序的C#客户端,并且失败了! 我通过剖析一个对此行起作用的python客户端来缩小问题范围:

def Startclient_Click(self, sender, e): try: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, int(port))) message = b'message "Render"' msg = struct.pack('<l',len(message))+struct.pack('<l',0)+message #print(msg) s.sendall(msg) data = s.recv(1024) data.decode("utf-8") self.datatxt.Text ="data: " +str(data) s.close() return except: self.datatxt.Text ="No Server Connection" return 

C#中的等价物是什么? 根据我的理解,它需要在消息之前8个字节

抱歉这个愚蠢的问题,但我已经在这几天了,我失去了生活的意愿,谢谢

struct.pack采用一种格式,后跟一系列将根据格式打包的值。 在你的问题中,你打电话:

 struct.pack(' 

这就是说“将这条消息的长度打包成一个小尾数,然后将一个零封装成一个小尾数,然后附加我的其余信息”。

当你在C#中遇到这种问题时,我们很遗憾没有struct.pack的直接端口。 您最接近的等价物是使用BitConverter进行一次性转换,例如:

 BitConverter.GetBytes((long)message.length) + BitConverter.GetBytes(0l) + message 

或者将BinaryWriter用于MemoryStream 。 这带来了另一个问题,即您无法使用这些工具控制字节序。 他们揭露了“IsLittleEndian”,所以你知道他们是如何行动但你不能改变它。

然而Jon Skeet就是这样的 - 他的MiscUtils库包含一个LittleEndianBitConverter(MiscUtil.Conversion.LittleEndianBitConverter),你可以使用它,或者你应该使用EndianBinaryWriter写一个Writer / MemoryStream路径。 所以把它们放在一起,引用MiscUtil库并使用类似的东西:

 var bytes = new List(new[] { LittleEndianBitConverter.GetBytes(message.LongLength), LittleEndianBitConverter.GetBytes(0l), message }); var msg = new byte[bytes.Sum(barray => barray.LongLength)]; int offset = 0; foreach (var bArray in bytes) { System.Buffer.BlockCopy(bArray, 0, msg, offset, bArray.Length); offset = bArray.Length; } 

代码未经测试,但应该给你一个合理的起点。 假设您的消息已经是一个字节数组,并且msg是您要返回的数组。 我们使用System.Buffer.BlockCopy,因为它是原始类型最有效的复制方法。

*编辑*

我在问题中采用了这个例子,并在IDEOne中为Python代码和C#中的等效 代码 模拟了一个快速脚本。 这里的结果是Struct.Pack('调用忽略了该字节,并没有将它添加到输出中,这可能是你绊倒的原因。 这导致输出太长8字节。

这些脚本应该指向正确的方向。 如果您仍然遇到问题,可以发布您尝试过的代码。

作为参考,Python中的完成代码:

 import struct message = b'message "Render"' msg = struct.pack(' 

在C#中:

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using MiscUtil.Conversion; public class Test { public static void Main() { var message = Encoding.ASCII.GetBytes("message \"Render\""); var lenc = new LittleEndianBitConverter(); var bytes = new List(new[] { lenc.GetBytes(message.LongLength), message }); var msg = new byte[bytes.Sum(barray => barray.LongLength)]; int offset = 0; foreach (var bArray in bytes) { Buffer.BlockCopy(bArray, 0, msg, offset, bArray.Length); offset = bArray.Length; } Console.WriteLine(BitConverter.ToString(msg).Replace("-", ":")); } }