From jeff.a.ryan at gmail.com  Mon May 18 21:01:21 2009
From: jeff.a.ryan at gmail.com (Jeff Ryan)
Date: Mon, 18 May 2009 14:01:21 -0500
Subject: [Rd] readBin on binary non-blocking connections (Windows & Unix
	differences/bugs)
In-Reply-To: <971536df0905181101n76cc8730u9fd9680ea404d7f3@mail.gmail.com>
References: <e8e755250905181040k593e8b5al4725972d109c4d8a@mail.gmail.com>
	<971536df0905181101n76cc8730u9fd9680ea404d7f3@mail.gmail.com>
Message-ID: <e8e755250905181201y11d698afj57cb5b54a1321057@mail.gmail.com>

Thanks Gabor.

Unfortunately read/writeLines won't work in this particular
application.  Nor does readChar, as the returned values are not of a
fixed size.  I need to read each unknown length "character" up until
an embedded null.  readBin does this (almost) perfectly.

My current workaround is to simply force blocking=TRUE on Windows
users, but that seems not to be the right answer.

An alternate approach may be to rewrite readBin to allow for some sort
of buffering mechanism.  If readBin first reads in data as raw(), it
would be possible to test for an error and return via some switch
statement the appropriate length zero vector.

The main issue is that by reading in raw bytes I have to explicitly
convert to the appropriate data types (nul terminated character
strings in this case).

The second (bigger?) issue is that all readBin calls would have to
first look to the buffer before reading from the connection again.
This would require the buffer to be available --- either as an R
connection addition, or as a global variable.

The best option of course is for readBin to correctly catch the error
cases, but without guidance from those who know the full details of
sockets in R, I am afraid that option isn't realistic at this moment.

Jeff





On Mon, May 18, 2009 at 1:01 PM, Gabor Grothendieck
<ggrothendieck at gmail.com> wrote:
> Ryacas uses non-blocking sockets and works across all platforms
> but uses readLines/writeLines, rather than readBin, to communicate with
> yacas. ?You could look at its source code in case it brings anything to mind.
>
> On Mon, May 18, 2009 at 1:40 PM, Jeff Ryan <jeff.a.ryan at gmail.com> wrote:
>> R-devel:
>>
>> I am encountering a consistency issue using socketConnection and
>> readBin with *non-blocking* connections on Unix and Windows XP (no
>> Vista to test).
>>
>> I am a bit confused by the behavior of *non-blocking* connections
>> under Windows specifically. ?When calling readBin on a non-blocking
>> connection when there is no data to read on the socket, the connection
>> under Unix will return a vector of zero-length matching the type of
>> the 'what' argument to the readBin call.
>>
>> The same call under Windows returns random data unless called with
>> what=raw(), which instead returns an error.
>>
>>
>> A simple example using two R processes to illustrate on one machine:
>>
>>
>> #########################################################################
>> # PROCESS 1 (Windows/Unix -- the same code for both):
>> #########################################################################
>>
>> # Open the connection and don't write anything
>>
>> s <- socketConnection(port=7777, server=TRUE, blocking=TRUE,open="ab")
>>
>> #########################################################################
>> # PROCESS 2 (Windows) use this to read:
>> #########################################################################
>>
>> s <- socketConnection(port=7777,blocking=FALSE,open="ab")
>> readBin(s, character())
>> readBin(s, character())
>> readBin(s, double())
>> readBin(s, raw())
>>
>> # > readBin(s, character())
>> # [1] "\020??\001@??\001 $?\001 $?\001 $?\001 $?\001 $?\001 $?\001
>> $?\001 $?\001 ...
>> # > readBin(s, character())
>> # [1] "X\n"
>> # > readBin(s, double())
>> # [1] 1.255609e-316
>> # > readBin(s, raw())
>> # Error in readBin(s, raw()) : negative length vectors are not allowed
>>
>> ##########################################################################
>> # Using a *nix, the above works as I would expect
>> #
>> # PROCESS 2 (Unixes -- this example OSX 10.4, but is consistent on
>> other flavors)
>> #########################################################################
>>
>> s <- socketConnection(port=7777,blocking=FALSE, open="ab")
>> readBin(s, character())
>> readBin(s, raw())
>> readBin(s, double())
>>
>> # > readBin(s, character())
>> # character(0)
>> # > readBin(s, raw())
>> # raw(0)
>> # > readBin(s, double())
>> # numeric(0)
>>
>> Is this a bug in R or Windows? ?Is there a workaround? ?I would like
>> to have readBin on non-blocking connections work consistently across
>> platforms. ?When data is present, both platforms behave consistently.
>> Incidentally, the readBin calls in my program are not using R as the
>> server, the above code is simply to illustrate the problem.
>>
>> The fact that the raw() returns an error on Windows seems to indicate
>> that the error is able to be caught, and could be tested for.
>>
>> One other interesting point of note; the character() calls on Windows
>> will return not just random data, but very non-random R type strings.
>> Somehow non-allocated memory is being read.
>>
>>> readBin(s, character(),100)
>> ?[1] "X\n"
>> ?[2] "spatch"
>> ?[3] ""
>> ?[4] ""
>> ?[5] "X\n"
>> ?[6] "ssion"
>> ?[7] "\002"
>> ?[8] "?$?\001?|?\001\030[?\001?N?\001?N?\001?$?\001\004"
>> ?[9] "H\024?\001\f\025?\001,??\001\002\002"
>> ?[10] "?\026?\001?$?\001\005"
>> ?[11] ""
>> ?[12] "s.logical"
>> ...
>> ?[75] "8}?\001?~?\001\020??\001?$?\001?}?\001?$?\001???\001
>> $?\001???\001?~?\0014~?\001???\001?|?\001???\001???\001\034}?\001???\001
>> $?\001?|?\001?\177?\001"
>> ?[76] "?$?\001?$?\001???\001\030??\001T??\001?$?\001?$?\001
>> $?\001???\0010??\001?$?\001?$?\001???\0014??\001
>> \177?\001X??\001\034??\001?$?\001???\001???\001
>> |?\001\004??\001???\0010\177?\001???\001?{?\001<??\001
>> $?\001???\001?}?\001 ??\001?$?\001?$?\001\024\177?\001
>> $?\001t??\001???\001?}?\001?$?\001?$?\001t|?\001?$?\001
>> $?\001?\177?\001???\001?|?\001 |?\001?$?\001d??\001
>> $?\001???\001x{?\001?$?\001"
>> ?[77] "' must be of length 1"
>>
>> This behavior has been noticed by me at least as early as 2.6, and is
>> currently seen under 2.9.0.
>>
>> Thanks for any pointers,
>> Jeff Ryan
>>
>>
>> --
>> Jeffrey Ryan
>> jeffrey.ryan at insightalgo.com
>>
>> ia: insight algorithmics
>> www.insightalgo.com
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>



-- 
Jeffrey Ryan
jeffrey.ryan at insightalgo.com

ia: insight algorithmics
www.insightalgo.com



[Rd] readBin on binary non-blocking connections (Windows & Unix differences/bugs)
Jeff Ryan