[PD-dev] [mrpeach/tcpserver]: full socket send buffer blocks pd
Martin Peach
martin.peach at sympatico.ca
Sat Dec 12 20:09:58 CET 2009
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
More information about the Pd-dev
mailing list