11-16-2008 11:30 PM
11-17-2008 01:25 AM
Hi SiegeX,
you can use the "Flatten to string" function only if you send a string, because only then the prefixed length is correct for TCP/IP.
Mike
11-17-2008 12:11 PM
SiegeX-
MikeS81 is correct. Can you not use typecast to fit your needs or you were just trying this other way out?
11-17-2008 12:29 PM
SiegeX wrote:
I noticed that the "Flatten to string" VI has a (default) option to prepend the array/string size to the binary output string. This got me thinking that I could use this rather than the typecast vi to convert my arbitrary data to a string, prepend the length and call TCP Write one time. On the other side of the connection I would then do your standard two TCP Read calls, the first one being 4bytes for the length, the 2nd one being whatever the length that is returned. However, no matter what I do, the 2nd TCP Read does not return anything. Is there no way to do two TCP Reads on one TCP Write? I thought 'buffered mode' might work, but it didn't. If there is no way to do this, what is the point of the prepend length option on the Flatten to string? Apparently it has no network application if you have to send the length on its own TCP Write.
I believe the issue is due to the nature of TCP. One transmit/recieve for each packet.
The option for the Flatten to String... is useful when writing files for "OTHER" languages.
Ben
11-17-2008 01:24 PM
If I understood you correctly, then the problem is that you are misinterpreting what the first 4 bytes are. It's not the number of bytes that follows. It's the number of elements. In the case of a string being the original data, then it's the same as the number of characters. But with an array, it will be the number of elements. The number of bytes will depend on the datatype.
If you were to open the "Simple Data Server" example VI and replace the typecasting with the Flatten to String function and place a string indicator on the output, then you will see that the string that would be sent would start off with 0000 00C8 (if set to Hex Display mode). C8 = 200. Thus, when you read the first 4 bytes with TCP Read you would get the number 200 meaning that you should expect 200 elements of an array, but the actual number of bytes to follow is 200 x 8 (size of DBL) = 1600. Thus, you can use a single TCP Write and 2 TCP Reads - you just have to do it correctly.
Also, be aware that the prepending only makes sense if you're dealing with a string or an array.
11-17-2008 02:03 PM - edited 11-17-2008 02:09 PM
I'm going to second what smercurio said. There is no problem with using two (or fifty) tcp reads to read data from one send. See attached example where I use two reads; you could modify it so that you read bytes one at a time using tcp read.
More likely your problem is that tcp write is not sending what you think, and that's probably due to Flatten To String's "prepend length" option. Honestly, I recommend you NEVER use this option. If you want to send the length, just measure the string length and prepend it. At least then you'll always know what you're sending.
The reason to avoid the auto-prepender is that does different things depending on the kind of input, and often that isn't what you want. It was introduced to LabView at the same time as the ill-considered "prepend array or string size" option in the LV 8+ Write To Binary File function (which also only fires in certain contexts, and which also defaults to true.) It just isn't an appropriate default in either case; not everyone out there programs in LabView and you shouldn't have to set "optional" arguments to false just to write binary files without corruption.
-Rob
The attached example is in LV 8.6
11-17-2008 02:05 PM - edited 11-17-2008 02:07 PM
11-17-2008 02:45 PM
Ben wrote:
I believe the issue is due to the nature of TCP. One transmit/recieve for each packet.
I'm not sure exactly what Ben meant here, but the way I read it it's not quite accurate. If you try to write too much data into one packet TCP will automatically segment it and reassemble it at the other end. Conversely you can execute multiple TCP writes and if they occur closely enough in time, the TCP stack will combine them into a single packet before sending it (look up Nagle's algorithm for more information). It's likely that doing a TCP Write for the data length, followed immediately by a second TCP Write for the data, will send a single packet identical to what would have been sent if you combined the length and data into a single TCP Write. On the receiving end you of course do not need to read a full packet at a time - you can read any number of bytes up to the total number in the receive buffer.
11-17-2008 04:31 PM
Thank you all for the info. It's funny, before I read any of the replies I made a VI to show what I was talking about and how it doesn't work, but it DOES work. And as a few of you mentioned, the problem was that I originally assumed the prepended portion was bytes not number of elements. When I discovered this error in my logic during my example, everything worked just fine. I cannot open a LV 8.6 VI as I'm only on 8.2 but here is my working example that I think must be pretty similar to what you wrote. I guess the take away from this is that you CAN do multiple reads on a single write, and maybe gain a teensy bit of performance by concatenating the string length on top of the binary string before sending it in to a TCP Write.
P.S. How does one modify their post on here?
11-17-2008 04:35 PM
SiegeX wrote:
P.S. How does one modify their post on here?
I'm pretty sure it's under Options, on the right edge of the bar above each message. You only have a certain amount of time after posting during which you can edit your message.