Problema: meu código de servidor de música, usando uma conexão TCP simples em um soquete de bloqueio, precisa transmitir bytes para um cliente (acontece ser um squeezebox da Logitech). Não é complicado - leia 64k de um arquivo, grave-o no squeezebox, repita. Está tudo rodando em uma LAN local não ocupada, e o servidor e o cliente squeezebox estão conectados ao mesmo switch. O squeezebox não consome o fluxo muito rapidamente, então o servidor, em praticamente qualquer hardware, não deve ter problemas para manter o cliente alimentado.
E quando o servidor é executado em um Raspberry pi 3B+, na verdade não há nenhum problema. Um pi zero provavelmente poderia acompanhar. Quando é executado no meu laptop Linux, idem, está tudo bem. Posso perguntar ao squeezebox periodicamente o quão cheio está o buffer interno e ele rapidamente chega a cerca de 99+% e permanece lá. As gravações do servidor (após as primeiras) passam a maior parte do tempo bloqueadas, como seria de esperar.
Mas eu movo o servidor para um Azulle Inspire rodando Linux, conectado ao mesmo switch, e algo dá muito errado. A música começa a tocar, mas rapidamente gagueja e morre. O squeezebox informa que o buffer está começando a encher, mas então algo trava e o buffer esvazia rapidamente (às vezes aumentando um pouco, então acho que algum tráfego passa, mas não o suficiente), interrompendo a música. O servidor afirma que continua escrevendo, embora as gravações demorem mais do que eu esperava.
Observe que o Azulle tem outras funções de rede ocasionais e todas funcionam bem, embora eu provavelmente não notaria pequenos atrasos de rede para a maioria desses outros aplicativos. Mas quando o servidor de música está em execução, o NUC (e a rede) ficam ociosos - isso não é um problema de CPU ou largura de banda.
Já tentei trocar cabos, trocar switches e usar portas diferentes nos switches. Eu tentei enviar tamanhos de buffer diferentes. Sem efeito. Tudo o que posso dizer é que há algo muito instável sobre a pilha TCP ou o hardware ethernet.
Como depuro isso? O laptop linux, que funciona muito bem, está executando o Linux 4.15.0-55-generic (e o apt upgrade não muda isso). O Azuelle está rodando Linux 4.15.0-64-generic, Mint. Eu não posso acreditar que há uma mudança radical no tratamento do TCP no 4.15.0. Eu não estou muito familiarizado com ferramentas como tcpdump, deixe ao longo da configuração do kernel ou depuração, então estou procurando por alguns ...
os tempos de ping entre o laptop Linux e o Azuelle são consistentemente em torno de 0,2 ms e 0,35 ms, com 0,33 ms típico.
Estou perdido. TIA.
Use tcpdump para capturar seu stream:
onde
iface
é a interface de rede exxx
é um dos dois números de porta.Em seguida, abra
out.cap
com wireshark e veja o que você pode fazer com o traço. Deve ser óbvio o que está acontecendo lá. Se não, poste novamente.FWIW, pelo que você está dizendo, parece um problema de MTU.
Bem, essa era a pista que eu precisava.
Eu encontrei isso quando fiquei curioso sobre os tamanhos de MTU:
/sys/class/net/enp1s0/mtu:1500 /sys/class/net/lo/mtu:65536 /sys/class/net/wlp2s0/mtu:1500
Tudo bem, mas o wlp parecia uma conexão sem fio. Sem fio? Isso estava mesmo ligado? Então eu fiz o tcpdump na interface wlp..., e vi uma mensagem que reconheci do protocolo e depois uma longa série de ACKs, e nada mais, e o streaming tocou alguns segundos de música e falhou.
Então desliguei o wireless e tentei novamente. Sem gagueira. Tudo liso.
O estranho é que o servidor está a poucos metros do ponto de acesso sem fio. Mesmo que estivesse usando, não deveria haver largura de banda suficiente. Eu me pergunto se, por algum motivo, ter os dois ao mesmo tempo causou algum problema, mas pensei que era impossível...