结构包等值C#

2024-09-26 22:52:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在构建一个连接到渲染应用程序的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字节才能发送消息

抱歉这个愚蠢的问题,但我已经在这个问题上好几天了,我失去了活下去的意志 谢谢


Tags: textself应用程序messagedata客户机returndef
1条回答
网友
1楼 · 发布于 2024-09-26 22:52:33

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

struct.pack('<l', len(message))+struct.pack('<l',0)+message

它的意思是“将此消息的长度打包为little-endian-long,然后将零压缩为little-endian-long,然后附加我的消息的其余部分”。在

当您在C中处理此类问题时,很遗憾我们没有结构包. 最接近的等效方法是使用BitConverter进行一次性转换,例如:

^{pr2}$

或者使用BinaryWriterMemoryStream。这带来了另一个问题,那就是你不能使用这些工具来控制endian-ness。他们揭露了“IsLittleEndian”,所以你知道他们的行为,但你不能改变它。在

然而,Jon Skeet正在处理这个问题,他的MiscUtils库包含一个小的indianbitconverter(MiscUtil.Conversion.LittleEndianBitConverter)如果您走Writer/MemoryStream路径,则可以使用EndianBinaryWriter。因此,将它们放在一起,参考MiscUtil库并使用类似以下内容:

var bytes = new List<byte[]>(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 code及其equivalent in C#创建了一个快速脚本。这里的关键在于Struct.Pack('<l', 0)调用忽略了字节,并且没有将它添加到输出中,这可能会让您感到困惑。这导致输出太长8字节。在

这些脚本应该为你指明正确的方向。如果你仍然有麻烦,你可以张贴你尝试过的代码。在

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

import struct
message =  b'message "Render"'
msg = struct.pack('<l',len(message)) + struct.pack('<l',0) + message
print(":".join("{0:x}".format(ord(c)) for c in msg))

在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<byte[]>(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("-", ":"));
    }
}

相关问题 更多 >

    热门问题