【问题标题】:Create binary data using Ruby?使用 Ruby 创建二进制数据?
【发布时间】:2009-12-05 19:25:25
【问题描述】:

我正在使用 ruby​​ 套接字,所以我最终尝试将一个 IP 数据包放在一起,然后我拿了一个 ip 数据包并尝试制作一个类似的新数据包。

现在我的问题是:如果数据包是:45 00 00 54 00 00 40 00 40 01 06 e0 7f 00 00 01 7f 00 00 01,这显然是十六进制,所以我将其转换为十进制,然后使用 .pack 方法转换为二进制数据,并将其传递给发送方法,然后Wireshark 向我展示了与我创建的非常不同的东西,我做错了什么???,我知道,但无法弄清楚:

@packet = 0x4500005400004000400106e07f0000017f000001 #i converted each 32 bits together, not like i wrote
@data = ""
@data << @packet.to_s
@socket.send(@data.unpack(c*).to_s,@address)

还有其他方法可以解决整个问题吗?例如,我可以直接将要发送的数据写入套接字缓冲区吗??

提前致谢。

【问题讨论】:

    标签: ruby linux sockets protocols binary-data


    【解决方案1】:

    从十六进制 Bignum 开始是一个新颖的想法,尽管我无法立即想到利用它的好方法。

    不管怎样,麻烦从 Bignum 上的 .to_s 开始,这将产生一个使用数字的十进制表示形式创建一个字符串的效果,让你离位更远,而不是更近。不知何故,您的 c* 似乎也丢失了引号。

    但是把它们放回去,然后你解压字符串,它会得到一个整数数组,它们是原始十六进制字符串的数值的十进制表示中数字的 ascii 值,然后你 .to_s 那(无论如何 IO 都会这样做,所以,至少没有责备)但是这会产生一个字符串,其中包含解压缩字符串的 ascii 数字的可打印表示,所以你现在距离最初的意图还有光年。

    >> t = 0x4500005400004000400106e07f0000017f000001
    => 393920391770565046624940774228241397739864195073
    >> t.to_s
    => "393920391770565046624940774228241397739864195073"
    >> t.to_s.unpack('c*')
    => [51, 57, 51, 57, 50, 48, 51, 57, 49, 55, 55, 48, 53, 54, 53, 48, 52, 54, 54, 50, 52, 57, 52, 48, 55, 55, 52, 50, 50, 56, 50, 52, 49, 51, 57, 55, 55, 51, 57, 56, 54, 52, 49, 57, 53, 48, 55, 51]
    >> t.to_s.unpack('c*').to_s
    => "515751575048515749555548535453485254545052575248555552505056505249515755555157565452495753485551"
    

    这在某种程度上很有趣。所有的信息都还在,有点。

    无论如何,您需要制作一个二进制字符串。要么只输入&lt;&lt; 数字:

    >> s = ''; s << 1 << 2 
    => "\001\002"
    

    或者使用Array#pack:

    >> [1,2].pack 'c*'
    => "\001\002"
    

    【讨论】:

    • 感谢您提供有趣的答案,但我已经像您指出的那样打包了最后一个,并写下了“我将每个 32 位转换在一起,不像我写的那样”,但是谢谢再次,你可能会暗示我正在寻找的答案。最后一件事,有没有另一种方法来解决整个问题,例如我可以直接将我想要发送的数据写入套接字缓冲区吗??
    • 好吧,你可以这样做:a = %w{45 00 00 54 00 00 40 00 40 01 06 e0 7f 00 00 01 7f 00 00 01}; @socket.send [a.join ''].pack('H*'), @address,或者,类似@socket.send(['45000054000040...'].pack('H*'), @address)
    【解决方案2】:

    首先检查您的主机字节顺序,因为您在 wireshark 中看到的是网络字节顺序 (BigEndian)。然后在wireshark中你会看到协议头(取决于它是TCP套接字还是UDP套接字),然后是数据。你不能直接发送IP数据包。因此,您可以在特定数据包的数据部分(即 TCP/UDP 数据包的数据部分)中看到此特定数据。

    【讨论】:

    • "不能直接发送IP包" ???你确定吗??,当我说Wireshark时,我在谈论标头,我还说我正在尝试创建一个数据包,所以这不是我们正在谈论的数据,这是我的标头试图创造。如果你弄错了,很抱歉没有很好地解释。
    猜你喜欢
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    相关资源
    最近更新 更多