![Socat이 TCP 연결을 닫지 않습니다.](https://rvso.com/image/1490203/Socat%EC%9D%B4%20TCP%20%EC%97%B0%EA%B2%B0%EC%9D%84%20%EB%8B%AB%EC%A7%80%20%EC%95%8A%EC%8A%B5%EB%8B%88%EB%8B%A4..png)
socat 1.7.3.1-r0
Linux 서버 에서 다음 명령을 사용 하고 실행합니다 alpine 3.3
.
socat -d -d -d PTY,link=/dev/ttyFOOBAR,echo=0,raw,unlink-close=0 TCP-LISTEN:7000,forever,reuseaddr
Socat
클라이언트를 수신하고 가상 직렬 포트에서 /dev/ttyFOOBAR
클라이언트로 데이터를 전달하고 TCP를 통해 다시 역방향으로 데이터를 전달하여 양방향 통신을 생성합니다. 클라이언트 연결이 끊어지면 socat
종료되어야 합니다.
이러한 연결이 설정되면 socat는 다음을 기록합니다.
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 ([email protected]) 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
문제는 클라이언트 연결을 끊을 때(클라이언트를 꺼서) 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
그런데 왜 연결 해제가 아닌 연결 시 이런 일이 발생합니까?
답변1
클라이언트를 종료하면 상대방에게 클라이언트가 종료된다는 사실을 알릴 기회가 없습니다. 피어가 사라졌음을 알 수 있는 유일한 방법은 피어에게 무언가를 보내고 응답하지 않는다는 것을 알아차리는 것입니다.
애플리케이션에서 데드 피어를 감지해야 하는 경우 데드 피어 감지를 구현해야 합니다. keepalive
에서 옵션을 활성화하여 이를 수행할 수 있지만 socat
데드 피어를 감지하는 데 여전히 몇 시간이 걸릴 수 있습니다. 주기적으로 무언가를 전송하여 이를 수행할 수도 있습니다. 피어가 작동하지 않으면 전송 시간이 초과되어 감지가 시작됩니다. 상대방이 당신에게 데이터를 보내기로 되어 있는 경우, 기대하는 데이터를 받지 못했다면(아마도 socat
의 -T
플래그를 사용하여) 중단할 수 있습니다.