[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 
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.


More information about the Pd-dev mailing list