当前位置: 首页 > 知识库问答 >
问题:

结构。包等效在C#?

程钧
2023-03-14

我正在构建一个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字节前的消息。

共有1个答案

孙子民
2023-03-14

struct.pack采用一种格式,后跟一系列值,这些值将根据格式进行打包。在你的问题中,你称之为:

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

也就是说“将此消息的长度打包为一个小尾端长度,然后将零打包为一个小尾端长度,然后再将我的消息的其余部分追加”。

当您在C#中处理此类问题时,不幸的是,我们没有struct.pack.的直接端口。您最接近的等价物将是使用BitConzer进行一次性转换,例如:

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

或者在MemoryStream中使用二进制编写器。然而,这带来了另一个问题,即您无法使用这些工具来控制endpoint。他们揭露了“IsLittleEndian”,所以你知道他们的行为,但你不能改变它。

然而,Jon Skeet就在这个案例中——他的MiscUtils库包含一个可以使用的LittleEndianBitConverter(MiscUtil.Conversion.LittleEndianBitConverter),或者一个EndianBinaryWriter,如果您使用Writer/MemoryStream的话。因此,将其放在一起,参考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.缓冲区。BlockCopy是对基元类型最有效的复制方法。

*编辑*

我以问题中的例子为例,在IDEOne中为Python代码及其在C#中的等价物模拟了一个快速脚本。这里的关键是结构。包

这些脚本应该为你指明正确的方向。如果你仍然有问题,你能发布你尝试过的代码吗?

作为参考,在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("-", ":"));
    }
}

 类似资料:
  • 问题内容: 我有一个带有几个子包的Python包。 在myproject.scripts.myscript中,如何访问myproject.models?我试过了 我以前必须解决此问题,但我永远不记得应该怎么做。这对我来说并不直观。 问题答案: 这是正确的版本: 如果失败,则是因为尚未设置包含的目录。 恐怕其他人会建议一些技巧,让您避免设置。我敦促您不要理them它们。这就是存在的原因:告诉Pyth

  • 运行时的基本检查 节点版本(>= 4) CLI 参数检查 包含所有可用和支持的CLI参数 检是否有冲突和弃用 统一存放日志 统一存放npmlog, winston和appium-logger 启动AppiumDriver(继承Basedriver) 为iOS/Android/Selendroid/Fake Driver 建立会话 创建/删除Appium会话 启动baseServer (appium

  • 包名 描述 aop 拦截器框架 castors 帮助你把任何类型转换成任何类型,从而让 Java 的类型不是那么的"强" dao 数据库访问接口,更薄,更简单轻便 el 嵌入式表达式引擎 filepool 文件池接口以及默认实现 http 简单的Http客户端工具类,帮助你发送 HTTP 请求 ioc Ioc 容器,你懂得 json JSON 的解析器和渲染器 lang 让 Java 的语法更加友

  • 问题内容: 我正在尝试学习Go并遵循现有的约定,但是,作为每个约定,您都需要先了解它们,然后才能很好地使用它们,经过一些研究,我没有找到以下问题的确切答案: 我已经在自己的内部建立了一个类似以下结构的项目: 我的主要是: 因此,问题是: 我读到我需要在每个package文件夹中都有一个文件,对吗? 如果是这样,在内部,我将如何导入,以及? 然后,是否可能会有类似的内容: …并且主要是做什么的? 问

  • 问题内容: 我正在尝试使用。我对处理包含数组的C结构感兴趣。考虑以下 并假设我已经将其编译到共享库中了从Python我可以做这样的事情 到目前为止一切顺利:我已经创建了正确的类型,并且一切似乎都正常。但是之后: 我显然缺少了一些东西。该类型是公认的(否则呼叫将抛出一个错误),但不正确初始化。 问题答案: 代码有2个问题(如我在评论中所述): print_array_struct.argtype-

  • 问题内容: 在Java Web应用程序中设置包结构的最佳实践是什么? 您将如何设置src,单元测试代码等? 问题答案: 您可以遵循maven的标准项目布局。您不必实际使用Maven,但这会使将来的过渡更加容易(如有必要)。另外,由于许多开源项目都是以这种方式进行布局的,因此其他开发人员将习惯于看到这种布局,