메시지가 잘린 Socat UDP 클라이언트/서버

메시지가 잘린 Socat UDP 클라이언트/서버

nodejs를 사용하면 50000자의 페이로드로 UDP 패킷을 전송할 수 있습니다. 하지만 socat(클라이언트와 서버 모두에서 Linux 우분투 20.04)에서는 그렇게 하지 못했습니다.

이 테스트에서는 집 호스트를 직장 호스트에 연결하는 VPN을 사용했습니다. 나는 socat을 사용하면 약간의 데이터 손실을 예상했지만 그 정도는 아닙니다!

원격(작업) 호스트에서 socat 서버는 50000바이트보다 큰 udp 응답을 다시 보내라는 요청을 기다립니다.

cat <<EOF > sotest.sh 
#!/bin/bash
head -c 50000 < /dev/zero | tr '\0' 'q'
EOF
chmod +x sotest.sh
socat udp4-listen:13000,reuseaddr,fork EXEC:"./sotest.sh" # server
#client
printf "trigger" |socat -T 5 -,ignoreeof udp4:10.50.1.184:13000,sndbuf=64000,rcvbuf=64000 > t.t 

메시지 크기를 확인하면 wc -c t.t50k 대신 약 8k 문자가 표시됩니다.

내 nodejs udp 클라이언트/서버를 사용하는 경우 서버에서 보낸 50k 문자 메시지가 nodejs 클라이언트에 의해 전체적으로 수신됩니다. 고객 :https://jsfiddle.net/xtcpL63a/ 섬기는 사람:https://jsfiddle.net/851fc7bp/

내가 가진 유일한 단서는 디버그 모드에서만 볼 수 있는 socat의 오류 메시지입니다.

022/12/03 22:37:40 socat[1051733] N forked off child process 1051734
2022/12/03 22:37:40 socat[1051733] N forked off child process 1051734
2022/12/03 22:37:40 socat[1051733] I close(7)
2022/12/03 22:37:40 socat[1051733] I resolved and opened all sock addresses
2022/12/03 22:37:40 socat[1051733] N starting data transfer loop with FDs [5,5] and [6,6]
2022/12/03 22:37:40 socat[1051733] I transferred 73 bytes from 5 to 6
2022/12/03 22:37:40 socat[1051734] I just born: child process 1051734
2022/12/03 22:37:40 socat[1051734] I close(4)
2022/12/03 22:37:40 socat[1051734] I close(3)
2022/12/03 22:37:40 socat[1051734] I close(6)
2022/12/03 22:37:40 socat[1051734] I dup2(7, 0) -> 0
2022/12/03 22:37:40 socat[1051734] I dup2(7, 1) -> 1
2022/12/03 22:37:40 socat[1051734] I close(7)
2022/12/03 22:37:40 socat[1051734] N execvp'ing "./sotest.sh"
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 8192 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] I transferred 848 bytes from 6 to 5
2022/12/03 22:37:40 socat[1051733] E read(5, 0x5566b4417150, 8192): Connection refused
2022/12/03 22:37:40 socat[1051733] N exit(1)
2022/12/03 22:37:40 socat[1051733] I shutdown(5, 2)
2022/12/03 22:37:40 socat[1051733] I shutdown(6, 2)

이 문제는 Linux 측의 버퍼와 관련될 수 없으며 MTU와 관련될 수도 없습니다. 그렇다면 socat에서는 무슨 일이 일어나고 있는 걸까요?

해결책: Tero Kilkanen이 문제를 지적했습니다. 클라이언트 측에서 socat이 더 큰 버퍼를 사용하도록 강제하면 메시지 전체를 수신할 수 있었습니다. 해결되었지만 실제로 이 동작을 설명하지는 않습니다...

#client
printf "${MSG}" |socat -b100000 -T 5 -,ignoreeof udp4:10.50.1.184:13000,sndbuf=64000,rcvbuf=64000 > t.t 

서버 측에서는 하나의 패킷이 전송되었는지 확인했습니다. 디버그 로그에서 동작의 차이를 확인할 수 있습니다.

socat -b100000 -d -d -d udp4-listen:13000,reuseaddr,fork EXEC:"./sotest.sh"

답변1

socat기본 버퍼 크기는 8k입니다. 클라이언트 측에서만 버퍼 크기를 설정합니다. 따라서 서버는 기본 8k 버퍼 크기를 사용합니다. 이것이 바로 패킷이 8k UDP 데이터그램으로 전송되는 이유입니다.

그런 다음 어떤 이유로 클라이언트는 서버가 보낸 첫 번째 UDP 데이터그램만 읽습니다.

관련 정보