我正在尝试使用 socat 设置中继服务器。用户向客户端发送请求,然后客户端在输入上应用 rot13 并将其转发到服务器,服务器再次应用 rot13 进行解密,最后将其传递到目标服务
# client
socat -dd tcp-listen:8443,fork=1 system:'bash -c "exec cat | tr A-Za-z N-ZA-Mn-za-m | socat -dd -v - tcp:localhost:8444"'
# server
socat -dd tcp-listen:8444,fork=1 system:'bash -c "exec cat | tr A-Za-z N-ZA-Mn-za-m | socat -dd -v - tcp:localhost:8445"'
# destination service
python3 -m http.server 8445
问题是,除非我按 ctrl+c(此时我看到预期的数据),否则不会返回数据。
这个命令(例如):
socat -dd tcp-listen:8443,fork=1 system:'bash -c "exec cat | tr A-Za-z N-ZA-Mn-za-m | socat -dd -v - tcp:localhost:8444"'
... 将在
socat
通道的一端设置 TCP 侦听套接字,并在另一端设置 one bash
进程。 第二端建立第二个 socat
通道,将一端的标准流连接到另一端的 one TCP 连接。
其中有一些您可能没有意识到的含义,包括:
进程的
stdout
通常会被缓冲,通常是完全缓冲。 这就是您的 socat
通道中所有 stdio 地址的情况。
所有传入连接都会将数据传递到通道另一端的同一个 shell,该 shell 会无限期地保持运行,直到
socat
终止。 因此,
如果有多个并发客户端,则将返回路径数据定向到正确的客户端可能会出现问题,并且
通道第二侧的脚本不会看到来自
socat
的 EOF,直到后者关闭。 关闭连接的个人客户是不够的。
由于采用 Nagel 算法来最大限度地减少传输许多小数据包的开销,因此每个 TCP 连接可能会有延迟。
这导致:
问题是,除非我按 ctrl+c(此时我看到预期的数据),否则不会返回数据。
您的数据正在所涉及的几个
stdout
中的一个或多个中进行缓冲,直到足够的数据(部分)被刷新,或者通道关闭。 由于您使用的是 Linux,因此您可以通过使用 stdbuf
命令 调整缓冲来解决此问题。 此外,您还可以从删除一些无关的进程中受益,例如额外的外壳包装和不必要的 cat
使用。 您还可以通过关闭 Nagel 算法来减少延迟。
我倾向于认为,沿着这些思路的东西会更适合你,尽管它可能仍然存在问题 - 也许是严重的问题 - 多个并发客户端:
socat -dd \
tcp-listen:8443,fork \
system:'stdbuf -o0 tr A-Za-z N-ZA-Mn-za-m | socat -dd -v - tcp:localhost:8444,nodelay'
socat -dd \
tcp-listen:8444,fork \
system:'stdbuf -o0 tr A-Za-z N-ZA-Mn-za-m | socat -dd -v - tcp:localhost:8445,nodelay'