如何使用Unix Socket在ruby和Python之间进行通信

时间:2022-01-06 10:24:45

I am trying to do some communication between my ruby process and Python process; and I want to use UNIX socket.

我试图在我的ruby进程和Python进程之间进行一些通信;我想使用UNIX套接字。

Objective: ruby process "fork and exec" the Python process. In ruby process, create a UNIX socket pair, and pass it to Python.

目标:ruby进程“fork和exec”的Python进程。在ruby过程中,创建一个UNIX套接字对,并将其传递给Python。

Ruby code (p.rb):

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 code (p.py):

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')

command line:

命令行:

ruby p.rb

Result:

结果:

OSError: [Errno 9] Bad file descriptor

I was hoping that the ruby process will pass the file descriptor to the python process, so that these two could send data using these socket.

我希望ruby进程将文件描述符传递给python进程,这样这两个就可以使用这些socket发送数据。

So, my question:

那么,我的问题是:

1) Is it possible to pass open file descriptor between ruby and python process as above?

1)如上所述,是否可以在ruby和python进程之间传递打开的文件描述符?

2) If we can pass around file descriptor between two processes, then what's wrong in my code.

2)如果我们可以在两个进程之间传递文件描述符,那么我的代码中有什么问题。

1 个解决方案

#1


5  

You were close, but Ruby spawn closes any file descriptors > 2 by default, unless you pass :close_others => false as argument. See the documentation:

你很接近,但Ruby spawn默认关闭任何文件描述符> 2,除非你传递:close_others => false作为参数。查看文档:

http://apidock.com/ruby/Kernel/spawn

http://apidock.com/ruby/Kernel/spawn

Working example:

工作范例:

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")

Test:

测试:

> ruby p.rb
Hello world

#1


5  

You were close, but Ruby spawn closes any file descriptors > 2 by default, unless you pass :close_others => false as argument. See the documentation:

你很接近,但Ruby spawn默认关闭任何文件描述符> 2,除非你传递:close_others => false作为参数。查看文档:

http://apidock.com/ruby/Kernel/spawn

http://apidock.com/ruby/Kernel/spawn

Working example:

工作范例:

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")

Test:

测试:

> ruby p.rb
Hello world