2016-10-16 21 views
1

私はCで書いた簡単なWebサーバー(非常に)を持っています。私はstdinでデータを受け取り、stdoutで送信するように書きました。どのように私はsocket.accept()で作成されたソケットの入出力は、subprocess.Popenで作成されたプロセスの入出力に接続するのですか?処理するPython接続ソケット

音はシンプルですね。ここではキラーです:私はWindowsを実行しています。

誰でも手助けできますか?

  1. を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". 
+0

[mcve]をお読みください。 – boardrider

+0

私は同じ問題がありましたが、私が思いついた解決策は、ソケットのポートをプロセスの標準に書き込むか、(socketで) 'socket.share'関数を使ってソケットを共有することでした。私はあなたが少なくともこのソリューションを検討すべきだと思います。興味深い。 –

答えて

1

は、私は同じ問題を持っていたし、また、Windows上で、ソケットをバインドするのと同じ方法を試してみました。私が出てきた解決策は、ソケットを共有して、プロセス上でstdinstdoutにバインドすることでした。私のソリューションは完全に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です。これが一定であるかどうかはわかりませんが、それは私のために働いていました。これは、ウィンドウでのみ可能です。share機能は、そのOSでのみ使用できます。

+0

'share()'と 'fromshare()'関数のCのようには見えないので、技術的に質問に答えないのでこれを受け入れません。しかし、これは非常に便利です。ありがとうございました。 – anonymoose

+1

これはWindows API呼び出しですが、Windows APIには同等の機能があります。[共有ソケット](https://msdn.microsoft.com/en-us/library/windows/desktop/ms740478(英語)) v = vs.85).aspx) –

関連する問題