Upv*_*ote 2 sockets tcp socat alpine-linux
我socat 1.7.3.1-r0在alpine 3.3linux服务器上使用并运行以下命令:
socat -d -d -d PTY,link=/dev/ttyFOOBAR,echo=0,raw,unlink-close=0 TCP-LISTEN:7000,forever,reuseaddr
Run Code Online (Sandbox Code Playgroud)
Socat将通过将数据从虚拟串行端口/dev/ttyFOOBAR传递到客户端并通过TCP再次返回来监听客户端并创建双向通信.一旦客户端断开连接就socat应该退出.
建立这样的连接时,socat会记录以下内容:
Run Code Online (Sandbox Code Playgroud)I socat by Gerhard Rieger - see www.dest-unreach.org I This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit. (http://www.openssl.org/) I This product includes software written by Tim Hudson (tjh@cryptsoft.com) I setting option "symbolic-link" to "/dev/ttyFOOBAR" I setting option "echo" to 0 I setting option "raw" I setting option "unlink-close" to 0 I openpty({5}, {6}, {"/dev/pts/3"},,) -> 0 N PTY is /dev/pts/3 I setting option "forever" to 1 I setting option "so-reuseaddr" to 1 I socket(2, 1, 6) -> 7 I starting accept loop N listening on AF=2 0.0.0.0:7000 I accept(7, {2, AF=2 CLIENT_IP:PORT}, 16) -> 8 N accepting connection from AF=2 CLIENT_IP:PORT on AF=2 172.20.0.2:7000 I permitting connection from AF=2 CLIENT_IP:PORT I close(7) I resolved and opened all sock addresses N starting data transfer loop with FDs [5,5] and [8,8]
ss 服务器上的命令打印:
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp ESTAB 0 0 172.20.0.2:7000 CLIENT_IP:PORT
Run Code Online (Sandbox Code Playgroud)
问题是,当我断开客户端(通过关闭它)时,仍然建立了tcp连接,并且没有来自socat的添加日志记录.ss仍显示连接为ESTAB.有什么想法吗?当我再次连接客户端时,会出现在日志中:
W read(8, 0x7fa8f48c4020, 8192): Connection reset by peer
N socket 2 to socket 1 is in error
N socket 2 (fd 8) is at EOF
I poll timed out (no data within 0.500000 seconds)
I close(5)
I shutdown(8, 2)
I shutdown(8, 2): Socket not connected
N exiting with status 0
Run Code Online (Sandbox Code Playgroud)
但为什么这会发生在连接而不是断开?
如果在套接字上没有要发送或接收的数据,并且您切断了基础连接,则在尝试发送数据之前,双方都不会知道.通常,这将是应用程序级别的数据,但在协议级别,您可以启用TCP keep alives以在没有实际数据时模拟流动数据.
根据socat手册页,您可以尝试以下方法:
socat -d -d -d PTY,link=/dev/ttyFOOBAR,echo=0,raw,unlink-close=0 TCP-LISTEN:7000,forever,reuseaddr,keepalive,keepidle=10,keepintvl=10,keepcnt=2
Run Code Online (Sandbox Code Playgroud)
(keepalive实际上看起来像是必不可少的选项,但如果未设置,则不清楚调整选项的默认值.)