Skip to search.
nsbasic-palm · NS Basic/Palm Web Board

Group Information

  • Members: 4181
  • Category: Basic
  • Founded: Jul 1, 2000
  • Language: English
? Already a member? Sign in to Yahoo!

Yahoo! Groups Tips

Did you know...
Real people. Real stories. See how Yahoo! Groups impacts members worldwide.

Messages

  Messages Help
Advanced
Tcp Help   Message List  
Reply Message #51155 of 57400 |
Re: [nsbasic-palm] Tcp Help

mhrds,

> Do Until Left(readData,3)="END"
> readData = TCP.TcpRead(fd, 100, "#", 2500)
> lbReceived.add readData
> Loop
>
>lbReceived receives Test1#Test2#END#
>It does not separate it out.
>
>Any help

It appears to me that this "feature" of TcpRead() is implemented wrong in the
library. Bear in mind that this library was contributed by a user, not
developed by NSB. The source for it is (or was?) available in the Files section
of this forum, so I checked my archives of that and found the following C code
snippet as part of the implementation of TcpRead:

do {
l = NetLibReceive(libref, s, data, len, 0, 0, 0, 0, &err);
if (l > 0) {
if (set) {
data[l] = 0;
if (strpbrk(data, set))
return 0;
}
data += l;
len -= l;
err = netErrTimeout;
}
SysTaskDelay(1);
} while (len > 0 && err == netErrTimeout && timeout--);

You may not understand C, but what the above code does is accept as many bytes
as are waiting in the TCP buffers using NetLibReceive(), up to a maximum of the
length you pass (100 in your example). If you supplied a matchset of
delimiters, strpbrk() is then used to see if any of them existed in the data
received. If so, the loop quits and returns to you. If not, then it reduces
"len" by the number of bytes already received and loops again waiting for more
characters. It stops either when any of your delimiters have been found, you
have read a total of "len" bytes, or you have reached your timeout value.

The obvious problem with the above implementation is that it accepts as many
bytes as are waiting in the TCP buffer, up to the remaining size of your buffer,
before it checks for a delimiter match in your matchset argument.

So what appears to be happening to you based on your post and my looking at the
library source, is that the entire "Test1#Test2#END#" data is available in the
Tcp buffer by the time it does its first NetLibReceive() call. It then detects
the presence of the # and immediately returns to you without asking for more
data, but by that point it has already read past the first # characters.

In other words, it looks to me like the library implementation is broke, or at
least deceiving in its description. The tech note simply says:

matchSet = string, up to 2 characters. TcpRead will return when one of these
characters are encountered.

Well, it will return when one of these characters is encountered so it is
technically correct. But what it doesn't say is that it may return beyond that
character if that data was already available in the TCP buffers.

It is aso interesting it says that matchset can be up to 2 characters long. The
C string library function strpbrk has no such limitation. It looks to me like
you can pass as many delimiters as you want in the string, though performance
may go down (very marginally) if the string is excessively long.

At any rate, the bottom line is that is looks like you aren't going to get
TcpRead() to stop *at* your delimiter, only to stop when the delimiter has been
found within the text it reads even though it may read beyond the delimiter
before figuring that out.

I'm sure that is not what you want to hear, but at least now you can stop
beating your head against the wall trying to make it work. I'd suggest you look
to NSBSystemLib's DelimitedItem() function to let you parse the text received by
your # delimiter.

Bear in mind that what you get back may be network timing dependent and won't
necessarily break on delimiters. For example, if the TCP buffer happened to
contain "Test1#Test2#E" on the first call to NetLibReceive(), then that is what
you'd get back from TcpRead(). The next call to TcpRead() would get "ND#" but
you'd never see it say "END" contigously. Therefore you may be much better off
using a larger buffer than 100 bytes (if necessary) and getting the entire text,
then using NSL's DelimitedItem() to walk all the substrings delimited by #.

Don't shoot me -- I'm just the messenger. I didn't write the library.

Doug



Sat Mar 4, 2006 2:16 am

douglashandy
Offline Offline
Send Email Send Email

Message #51155 of 57400 |
Expand Messages Author Sort by Date

I am in the testing mode of trying a loop to receive data I tried several things to make it read next line "#" is not returning results Test from my server...
mhrds Offline Send Email Mar 4, 2006
1:09 am

mhrds, ... It appears to me that this "feature" of TcpRead() is implemented wrong in the library. Bear in mind that this library was contributed by a user,...
Douglas Handy
douglashandy Offline Send Email
Mar 4, 2006
2:17 am
Advanced

Copyright © 2010 Yahoo! Inc. All rights reserved.
Privacy Policy - Terms of Service - Guidelines NEW - Help