如何在Ruby与Python之间使用Unix套接字进行通信
我正在尝试让我的 Ruby 程序和 Python 程序之间进行一些通信,我想使用 UNIX 套接字。
目标: 在 Ruby 程序中“分叉并执行” Python 程序。在 Ruby 程序里,创建一对 UNIX 套接字,并把它传给 Python。
Ruby 代码 (p.rb):
require 'socket'
r_socket, p_socket = Socket.pair(:UNIX, :DGRAM, 0)
# I was hoping this file descriptor would be available in the child process
pid = Process.spawn('python', 'p.py', p_socket.fileno.to_s)
Process.waitpid(pid)
Python 代码 (p.py):
import sys
import os
import socket
# get the file descriptor from command line
p_fd = int(sys.argv[1])
socket.fromfd(p_fd, socket.AF_UNIX, socket.SOCK_DGRAM)
# f_socket = os.fdopen(p_fd)
# os.write(p_fd, 'h')
命令行:
ruby p.rb
结果:
OSError: [Errno 9] Bad file descriptor
我希望 Ruby 程序能够把文件描述符传给 Python 程序,这样这两个程序就可以通过这些套接字发送数据。
所以,我的问题是:
1) 是否可以像上面那样在 Ruby 和 Python 程序之间传递打开的文件描述符?
2) 如果我们可以在两个程序之间传递文件描述符,那我的代码有什么问题呢?
1 个回答
5
你说得差不多,但在Ruby中,spawn
这个方法默认会关闭所有编号大于2的文件描述符,除非你传入参数:close_others => false
。你可以查看文档了解更多信息:
http://apidock.com/ruby/Kernel/spawn
下面是一个工作示例:
require 'socket'
r_socket, p_socket = Socket.pair(:UNIX, :DGRAM, 0)
pid = Process.spawn('python', 'p.py', p_socket.fileno.to_s,
{ :close_others => false })
# Close the python end (we're not using it on the Ruby side)
p_socket.close
# Wait for some data
puts r_socket.gets
# Wait for finish
Process.waitpid(pid)
Python示例:
import sys
import socket
p_fd = int(sys.argv[1])
p_socket = socket.fromfd(p_fd, socket.AF_UNIX, socket.SOCK_DGRAM)
p_socket.send("Hello world\n")
测试代码:
> ruby p.rb
Hello world