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

Jeff Ryan jeff.a.ryan at gmail.com
Mon May 18 19:40:14 CEST 2009


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



More information about the R-devel mailing list