We have a lot of different variables at play here: song size, song bitrate, LMS, squeezelite, squeezelite stream buffer, server TCP send buffer, client TCP receive buffer, server TCP FIN timeout. Lets briefly look into what each of these contribute.
Song size and song bitrate - we don't have any control over these, but they obviously play big role in this failure. Song needs to be big enough to fill all the buffers and bitrate needs to be low enough to slow down how fast buffers are drained. Most of the songs do not meet requirements to trigger this issue though. LMS is not really doing anything wrong, it sends the data out as fast as it can and once all of the data is written to the socket it closes it. squeezelite is also not at fault here, it is reading data as fast as it can and suddenly socket disappears on it. I ran this same test with squeezeplay and failure mode was exactly the same. Squeezeplay uses larger buffer size 3145728 (vs 2097152) so everything failed closer to the end of the song. TCP send buffer - the size of this buffer does not really matter, because kernel TCP stack sends TCP FIN packet to the client only after this buffer is emptied. squeezelite stream buffer - this can be increased and it will reduce how often this issue happens, but it will not eliminate the issue. You can always find file that will be larger than the buffer size. TCP receive buffer and TCP FIN timeout - the combination of these is what causes the issue. If the TCP receive buffer is larger than the TCP FIN timeout multiplied by the song bitrate, we are going to have a failure. To test this I have increased TCP FIN timeout (net.ipv4.tcp_fin_timeout) on the server from 60 sec to 120 sec and that of course allowed enough time for the client to finish reading data from the TCP buffers. Client finished reading data 84 seconds after server finished sending data. 34910 What are some of the possible solutions? Haven't given much thought to these, so some might not make sense. Increasing squeezelite stream buffer - that's what most of the people that experience this issue are doing now. Increasing TCP FIN timeout (net.ipv4.tcp_fin_timeout) on the server - it is a system wide setting and might not be a good idea if LMS is not running on the dedicated box. LMS setting FIN time out on the socket level using SO_LINGER - not sure if this is possible though. Squeezelite explicitly setting TCP receive buffer size on the socket level using SO_RCVBUF - is this possible. LMS waiting to close the socket until Squeezelite notifies it that all of the data was received - this would be the only way to cover 100% of the cases, but is this possible to do? Thanks for reading and sorry for the long posts! +-------------------------------------------------------------------+ |Filename: tcp_session_ok_large_fin_timeout.jpg | |Download: http://forums.slimdevices.com/attachment.php?attachmentid=34910| +-------------------------------------------------------------------+ ------------------------------------------------------------------------ lngxa's Profile: http://forums.slimdevices.com/member.php?userid=71826 View this thread: http://forums.slimdevices.com/showthread.php?t=114661 _______________________________________________ Squeezecenter mailing list [email protected] http://lists.slimdevices.com/mailman/listinfo/squeezecenter
