如何在Ruby与Python之间使用Unix套接字进行通信

2 投票
1 回答
2331 浏览
提问于 2025-04-17 14:19

我正在尝试让我的 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

撰写回答