Roman Haefeli wrote:
Hi Martin
Hi Roman, sorry for the late reply.
I wasn't sure, if I should report that as a bug. The new version of [tcpserver] seems to work fine, BUT now it suffers again from the initial problem, that maxlib's [netserver] is still suffering from:
If the send buffer of a certain socket is full, [tcpserver] is blocked and thus blocks Pd.
From a user perspective, i can think of a few solutions to deal with
that. However, i don't have clue, what's possible/difficult to implement.
a) If the server doesn't get the necessary ACKs in a meaningful time, if shuts down the connection after a while.
It's up to the OS to deal with ACKs. The programmer has no (easy) way of accessing the low-level TCP communications. The send() function puts the data in the queue and returns. If the queue is blocked you don't find out until much later. The connection is closed some minutes after the disconnect occurs.
b) Instead of writing to the send buffer, [tcpserver] could output a message saying, that the data couldn't be sent.
Except it doesn't know the data couldn't be sent. I tried unplugging the cable and then plugging it back in. Sometimes all the data that was sent in the meantime will suddenly appear at the client, a few minutes after it was sent from the server. Other times I get 'client disconnected' messages a few minutes after the cable was unplugged. The timeout could probably be adjusted with the Time To Live parameter for the socket but it won't ever be zero. The internet protocols were designed to work over broken networks so it's normal that they wouldn't fail at the first attempt to send. UDP was intended for 'send and forget' messages. Maybe you could try [udpsend] to send vast quantities of data, alongside [tcpserver] for control. The previous incarnation of [tcpserver] used select() to see if there is still room in the buffer but as we saw this slows the whole thing to a crawl since the buffer has to be checked for every single byte in case it just filled up. It seems more efficient to have the client reply when it gets the message.
c) Change the behaviour of the 'sent' message from last outlet so, that it reflects the amount of bytes actually transmitted and not the number of bytes written to the send buffer.
Again 'it thinks' the data _was_ sent, so it returns the amount that it sent, even if it is still in the queue on the server, as long as the connection is still open.
d) <put something here, that i didn't think of>
I think you need to incorporate some kind of feedback from the clients. Either each client could send a request or a heartbeat every second or so, or the server could require a response to each message before sending more. Or use a separate UDP channel for the kind of data that could rapidly fill a buffer, like audio.
Martin