Используя nodejs я могу передавать udp-пакеты с полезной нагрузкой 50000 символов. Но мне не удаётся сделать это с socat (Linux ubuntu 20.04 на клиенте и сервере).
Для этого теста я использовал vpn, соединяющий мой домашний хост с моим рабочим хостом. Я ожидал некоторой потери данных с socat, но не до такой степени!
На удаленном (рабочем) хосте сервер SOCAT ждет запроса, чтобы отправить обратно раздутый ответ UDP размером > 50000 байт.
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.t
дает мне около 8 тыс. символов вместо 50 тыс.
Если я использую свой клиент/сервер nodejs udp, то сообщение длиной 50 тыс. символов, отправленное сервером, будет получено клиентом nodejs целиком. client :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?
Решение: Теро Килканен указал на проблему. Заставив 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. Вот почему пакеты отправляются в датаграммах UDP размером 8k.
Затем по какой-то причине клиент считывает только первую UDP-дейтаграмму, отправленную сервером.