[PD] tcpclient sending more than 1 send at once

Martin Peach martin.peach at sympatico.ca
Mon Sep 8 00:58:02 CEST 2008


Roman Haefeli wrote:
> On Sun, 2008-09-07 at 12:23 -0400, Martin Peach wrote:
>> Enrique Erne wrote:
>>> hi martin and the list
>>>
>>> if i send [send 11, send 22, send 33, send 44, send 55(
>>> to [tcpclient] the [tcpserver] prints
>>>
>>> receive: 11 22 33 44 55
>>>
>>> actually i expected to get 5 messages back. is this a bug or am i wrong?
>> It's unanticipated behaviour I guess...it also happens if you send the 
>> values as separate messages with a single bang. If you put a chain of 
>> massages separated by [delay]s you can find the shortest delay that 
>> sends them all separately.
>> I find that I need a delay of at least 8ms between messages for them to 
>> be transmitted separately. It's up to the implementation of TCP in the 
>> machine to decide when to send a packet. Probably UDP would send them 
>> all individually.
> 
> yo.. i would say, that it is not only unanticipated behaviour, but a
> bug, either in [tcpclient]/[tcpserver] or [unpackOSC]. from what i
> understand, it is a misconcept of [unpackOSC].
> 

IMHO it's not a bug. It's the way TCP is supposed to work. If more data 
arrives before the previous data has been sent, it all gets sent together.

Pd sends all its messages in between audio blocks, so a comma-separated 
list of messages will all go at the same time.

There is an option to set TCP_NODELAY on the socket, which I tried today 
but it has no real effect on WinXP at least, probably because the data 
is arriving too fast from Pd for it to be separated into packets

> please correct me, if interprete things the wrong way, but from my tests
> [tcp*] and [unpackOSC] don't work 'well' together. [tcp*] seem to not
> know anything about messages, they simply treat any incoming data as a
> stream (without any concept of delimiters). depending on how quickly you
> send messages to the sending object, the receiving object makes one or
> more pd messages out of it (this most likely happens on the tcp layer,
> where pd/[tcp*] assumingly doesn't have any influence on).

Sounds correct to me. UDP sends atomic 'datagrams' of up to a maximum 
size but TCP can send messages of arbitrary length by splitting it into 
packets and reassembling them at the other end, so there is no way of 
knowing when the data is finished unless it is encoded in the data.

> [unpackOSC]
> on the other hand is 'stream agnostic', it only accepts input as
> messages with correct number of elements. messages that are longer than
> one OSC packet are truncated to exactly one OSC packet, while the rest
> is silently ignored. if one message to [unpackOSC] is too short,
> [unpackOSC] drops an error:
> 
> unpackOSC: packet size (19) not a multiple of 4 bytes: dropping packet
> 
> from what i can tell, [tcp*] and [unpackOSC] are incompatible, since the
> former are 'message agnostic' and the latter is 'stream agnostic'.
> 
> if i am right about this, i really hope, that it could be fixed in some
> way. my suggestion would be to change [unpackOSC] in way, so that it
> treats incoming messages as a [stream] (in other words: it would
> completely disregard messages and always give an output, as soon as an
> OSC packet is completed).

Yes, [unpackOSC] should probably check to see if more OSC packets are 
present in its buffer after it has processed the first packet. A problem 
arises if there is only a partial packet there, but that shouldn't 
happen unless the whole thing is too long.

> 
> this is no problem as long as you use [unpackOSC] together with [udp*],
> since then you would expect some messages to drop. but when going the
> tcp route, you'd expect completeness on the receiving side. currently it
> is not possible to rely on this, as this little test shows:
> 
> [send /test 1, send /best 2(
> |
> [packOSC]
> |
> [tcpclient]
> 
> [tcpserver]
> |
> [unpackOSC]
> |
> [print]
> 
> it prints:
> 
> /test 1

Yes, and [unpackOSC] has no way of knowing if it is getting data from 
UDP or TCP so it should probably assume the worst and go for TCP. In 
fact, to be unbreakably robust it should assume it is getting input one 
byte at a time and not output anything until either an entire OSC packet 
has been received or the packet is not valid OSC.

Martin




More information about the Pd-list mailing list