リモートサーバーへのTCP接続を作成し、socat
クライアントが送信します。
- 画像ファイルの操作(
"convert"
、"open"
など) - イメージ(バイナリコンテンツ)自体
その後、サーバーは与えられたタスクを使用して画像を処理します。
私の最初の考えは、バイナリコンテンツの前にこのテキスト操作タイプを渡すことでした。
# client
socat tcp:server:9999 -\
< <(echo "open"; cat path/to/imgfile)
# server
socat tcp-listen:9999 - | {
IFS= read -r action
cat - > /tmp/imgfile
# do process image file with action type ...
}
これは特定の状況では機能しているように見えますが、複数のパラメータを渡す必要がある場合など、柔軟ではありません。また、バイナリコンテンツの前にテキストを追加すると、画像ファイルが破損している可能性があります。
だから私は2つのパラメータを1つずつ渡すよりきれいな解決策を見つけようとしました(ここでは二重通信と呼ばれます)。
これまで私が試したことは、次の分野の専門家ではないということですsocat
。
# client
socat\
tcp:server:9999\
system:'echo "open"; IFS= read -r ack; cat path/to/image.png'
# server
socat tcp-listen:9999\
system:'IFS= read -r action; echo "ACK"; binary=$(cat -); echo "process image with action now..."'
今は許してください
壊れたパイプ
このタイプの二重通信は可能ですかsocat
(新しいポートを開かない最良の場合)。
より簡単な選択肢を考えてみましたか?
おそらくこれはもはやフレームを使用せず、可能であればHTTPサーバーのオーバーヘッドなしで最も簡単で簡単な方法で行う必要があると言いたいと思います。シェルはBashであり、利用可能なZSHはありません。一般的なPythonを使用できます。
ベストアンサー1
socatを使用してこのタイプの二重通信が可能ですか(新しいポートを開かない最良の場合)。
いいえ。しかし、それはそれとは何の関係もありませんsocat
。 TCP接続が閉じられ、使用できなくなりました。しかし、特にcat -
Stéphaneが指摘したように、あなたのメカニズムは接続を閉じることに依存しています。
シェルはBashであり、利用可能なZSHはありません。一般的なPythonを使用できます。
だから、普通のPythonです。
~から 含まれるモジュールのPythonドキュメント、実際にはわずかに修正されました。
from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler
PORT = 8000
class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/RPC2',)
with SimpleXMLRPCServer(('localhost', PORT),
requestHandler = RequestHandler,
use_builtin_types = True) as server:
server.register_introspection_functions()
# Register a function under function.__name__.
@server.register_function
def convert(target_format: str, img: bytes):
# do something with img instead of just returning it,
# but you get the idea.
return img
@server.register_function
def length(img: bytes):
return len(img)
server.serve_forever()
クライアント側では
import xmlrpc.client
PORT = 8000
server_handle = xmlrpc.client.ServerProxy(f'http://localhost:{PORT:d}',
use_builtin_types = True)
with open("inputimage.jpg", "rb") as infile:
converted = server_handle.convert("image/png", infile.read())
with open("outputimage.png", "wb") as outfile:
outfile.write(converted)
# Print list of available methods
print(server_handle.system.listMethods())
これは確かに一般的なPythonであることに注意してください。xmlrpc.server
標準のPythonにはそれ以上もsocket
含まれていませんmath
。
ここからバニラの概念を拡張できます。venv
これはPython標準ライブラリの一部でもあります。あなたは本当に良いと思います。持つ標準のPythonです。
python3 -m venv serverstuff
. serverstuff/bin/activate
pip install Flask
もう少し快適にしてください。その後、次のようなサーバーを作成できます。クイックスタートの例:
from flask import Flask
from flask import request
from flask import Response
app = Flask(__name__)
@app.route("/")
def say_hello():
return "helloo"
@app.route("/convert/<target_fmt>"):
def convert(target_fmt):
print(target_fmt)
try:
infile = request.files["file"]
except Exception as e:
print(e)
return Response(response="", status=406)
# convert it; infile is a Werkzeug.Filestorage
# https://werkzeug.palletsprojects.com/en/2.3.x/datastructures/#werkzeug.datastructures.FileStorage
data = infile.read()
return Response(response=data, mimetype=f"image/{target_fmt}", status=200)
として保存server.py
して実行しますpython3 -m flask --app server run --port 8000
。
これにより、クライアント側のシェルスクリプトが非常に簡単になります。
$ myfiletoupload=/home/mosaic/catpicture.jpg
$ curl http://127.0.0.1:8000/convert/png -F "file=@${myfiletoupload}"