Ruby TCPSocket发送/接收二进制数据 - >数组哈希等

时间:2013-03-01 07:28:29

标签: ruby sockets tcp binary protocols

我正在尝试在Ruby中创建自定义游戏服务器协议,但我无法理解我可以/应该做些什么:

Q-→1#

服务器使用TCPServer / TCPSocket向客户端发送数组。但我不能使用JSON,因为传输需要二进制..如何将ruby数组转换为二进制,然后可以转换回客户端的数组?

这是我的服务器:

#!/usr/bin/env ruby

require 'socket'

server = TCPServer.new 5020

loop do
    Thread.start(server.accept) { |c|
        print "new Client connected" 
        a = ["Hello, there"]

        payload_with_header = CustomProtocolModule.constructMethod(a) # what method do i use to convert a (array -> binary representation?  don't really understand .unpack, .pack, what template would i use if i did use String#Unpack? will String#Unpack work for what i need?
        client.write payload_with_header
        client.close
    }
end

(以上是我的第一个问题)

Q-→2#

接下来,因为我知道我需要使用某种终止来检查消息的结束或确定客户端/服务器是否已收到完整消息的方法我可以设置有效负载的前两个字节以包含大小消息?我该怎么做这个服务器端&客户端?接收方必须循环TCPSocket.recv?直到它收到前两个字节(标题),然后读取前两个字节包含的大小?这样的事情就是我想到的:

| Payload Header  (2 bytes) | array (contains cmd, message etc) |

如果有人可以帮助指导我正确的方向和/或提供可以提供帮助的伪代码。这将不胜感激。具体来说,我对如何循环标头感兴趣,然后将有效负载读回数组并构建有效负载标头。

谢谢!

1 个答案:

答案 0 :(得分:1)

payload_with_header = CustomProtocolModule.constructMethod(a) 

您可以使用

序列化
payload = Marshal.dump(a) 

然后你可以使用

[payload.length].pack('l>') # to create a big endian signed long integer size for the packet

另一方面,您可以从套接字读取整数,然后读取二进制文件并使用

反序列化
array= Marshal.load(read_binary)

这几乎适用于所有数据结构。 Proc实例是一个例外。

Ruby also supports remote objects and procedure calls所以你可以进行进程间通信,即使是在不同的ruby实现之间(例如JRuby和MRI)