Python连接套接字到进程

6
我编写了一个非常简单的C语言Web服务器,我想测试它。我编写它以便从stdin获取数据并通过stdout发送出去。如何将socket(使用socket.accept()创建)的输入/输出连接到使用subprocess.Popen()创建的进程的输入/输出?
听起来很简单,对吧?但问题在于:我正在运行Windows。
有人能帮忙吗?
这是我尝试过的内容:
1. 将客户端对象本身作为stdin/out传递给subprocess.Popen。(尝试一下也无妨。) 2. 将socket.makefile()结果作为stdin/out传递给subprocess.Popen。 3. 将套接字的文件编号传递给os.fdopen()。
此外,为了避免问题不清楚,这里是我的代码精简版本:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', PORT))
sock.listen(5)
cli, addr = sock.accept()
p = subprocess.Popen([PROG])
#I want to connect 'p' to the 'cli' socket so whatever it sends on stdout
#goes to the client and whatever the client sends goes to its stdin.
#I've tried:
p = subprocess.Popen([PROG], stdin = cli.makefile("r"), stdout = cli.makefile("w"))
p = subprocess.Popen([PROG], stdin = cli, stdout = cli)
p = subprocess.Popen([PROG], stdin = os.fdopen(cli.fileno(), "r"), stdout = os.fdopen(cli.fileno(), "w"))
#but all of them give me either "Bad file descriptor" or "The handle is invalid".

请阅读 [mcve]。 - boardrider
我曾经遇到过同样的问题,但是我想出来的解决方案是共享套接字,将套接字端口写入进程的标准输入或使用socket.share函数(在Python中)。我认为你至少应该考虑这个解决方案。 - Rolando Urquiza
1个回答

3

我曾经遇到同样的问题,并尝试使用同样的方法绑定套接字,也在Windows上进行了测试。我想出的解决方案是共享套接字并将其绑定到进程的 stdin stdout 。我的解决方案完全是用Python编写的,但我认为它们很容易转换。

import socket, subprocess

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', PORT))
sock.listen(5)
cli, addr = sock.accept()

process = subprocess.Popen([PROG], stdin=subprocess.PIPE)
process.stdin.write(cli.share(process.pid))
process.stdin.flush()

# you can now use `cli` as client normally

在另一个进程中:
import sys, os, socket

sock = socket.fromshare(os.read(sys.stdin.fileno(), 372))
sys.stdin = sock.makefile("r")
sys.stdout = sock.makefile("w")

# stdin and stdout now write to `sock`

372是一个被测量的socket.share调用的len。我不知道这个值是否是恒定的,但它对我有效。这只在Windows上可行,因为share函数仅在该操作系统上可用。


有趣。看起来没有C语言等价的share()fromshare()函数,所以我不会接受这个答案,因为从技术上讲它并没有回答问题。但是这非常有用。谢谢。 - anonymoose
1
这是一个Windows API调用,但在Windows API中有一个等效的函数,你可以在这里阅读它:共享套接字 - Rolando Urquiza

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接