[R-pkg-devel] socketConnection, delay when reading from

Ben Engbers ben@engber@ @end|ng |rom gm@||@com
Tue Dec 7 23:49:02 CET 2021


Hi Tomas,

I have implemented your suggestions as follows: (I'm not certain yet if 
the first check in done - total_length == 0 is realy needed)

Creating the socket:

CreateSocket = function(host, port = 1984L, username, password) {
   tryCatch(
     {conn <- private$conn <- socketConnection(
       host = "localhost", port,
       open = "w+b", server = FALSE, blocking = FALSE, encoding = "UTF-8")
     }, error = function(e) {
       stop("Cannot open the connection")
      }
   )

#### Authenticating

response <- readBin_(conn) %>% rawToChar()
===> # browser()
splitted <-strsplit(response, "\\:")
ifelse(length(splitted[[1]]) > 1,
   { realm <- splitted[[1]][1]
     code  <- paste(username, realm, password, sep=":")
     nonce <- splitted[[1]][2] },
   { code  <- password
     nonce <- splitted[[1]][1]}
   )
code <- md5(paste(md5(code), nonce, sep = "")) %>% charToRaw()
# send username + code
auth <- c(charToRaw(username), as.raw(0x00), code, as.raw(0x00))
writeBin(auth, private$conn)
Accepted <- readBin(conn, what = "raw", n = 1) == 0x00
if (!Accepted) {
close(private$conn)
stop("Access denied")
}


Reading from the socket:

done <- function(rd, total_length) {
   if (total_length == 0) {   to done
     finish <- FALSE
   } else {
     finish <- ifelse(length(rd == Bsize), FALSE, TRUE)
   }
   return(finish)
}

readBin_ <- function(conn) {
   total_read <- rd <- as.raw(c())
   while(!done(rd, length(total_read))) {
     rd <- readBin(conn, "raw", Bsize)
     total_read %<>% c(rd)
     }
   return(total_read)
}

The first time readBin is used is while authenticating a new session.
This code fails ;-(

But when I insert a  call to browser() after the first authentication 
line, I can execute all the following code without problems. This 
results in a fully functional session. And all the other following calls 
to readBin_ return the correct data.
This means that 'done' and 'readBin' do exactly what they are intended 
to do.

Question
Why does creating and authenticating fail when a call to browser() is 
missing? (Or why does authentication succeed after I have debugged

Best,
Ben

Op 27-11-2021 om 20:19 schreef Tomas Kalibera:
> On 11/27/21 8:05 PM, Tomas Kalibera wrote:
>>
> 
> This is an extended demo with socketSelect() used to wait on the client 
> for some data to be available, to avoid consuming too much CPU by 
> polling. To be pasted into two R sessions running on the same computer.
> You would have to replace the function done() with something figuring 
> out from the data whether it is complete or not, based on the protocol.
> 
> Best
> Tomas
> 
> 
> # the client
> 
> con2 <- socketConnection("localhost", port = 6011, open = "rb")
> cat("Connected...\n")
> total <- 0
> 
> done <- function(n) {
>    n >= 2e8
> }
> 
> while(!done(total)) {
>     cat("Waiting for data to become ready...\n")
>     socketSelect(list(con2))
>     cat("Reading data...\n")
>     r <- readBin(con2, "raw", 1024)
>     total <- total + length(r)
>     cat("Read", length(r), "bytes (total ", total, ").\n")
> }
> close(con2)
> 
> # the server
> 
> n <- 1e8
> w <- as.raw(runif(n, 0, 255))
> con1 <- socketConnection(port = 6011, blocking = TRUE, server = TRUE, 
> open="a+b")
> cat("Connected...\n")
> writeBin(w, con1)
> cat("Sent data the first time, sleeping...\n")
> Sys.sleep(10)
> cat("Sending data the second time...\n")
> writeBin(w, con1)
> cat("Data sent to client...\n")
> close(con1)
> 
>>
>> Best
>> Tomas
>>
>> # the client
>>
>> con2 <- socketConnection("localhost", port = 6011, open = "rb")
>> cat("Connected...\n")
>> total <- 0
>>
>> done <- function(n) {
>>   n >= 1e8
>> }
>>
>> while(!done(total)) {
>>    r <- readBin(con2, "raw", 1024)
>>    total <- total + length(r)
>>    cat("Read", length(r), "bytes (total ", total, ").\n")
>> }
>> close(con2)
>>
>> # the server
>>
>> n <- 1e8
>> w <- as.raw(runif(n, 0, 255))
>> con1 <- socketConnection(port = 6011, blocking = TRUE, server = TRUE, 
>> open="a+b")
>> cat("Connected...\n")
>> writeBin(w, con1)
>> cat("Data sent to client...\n")
>> close(con1)
>>
>>>
>>> Ben
>>>
>>> ______________________________________________
>>> R-package-devel using r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-package-devel


More information about the R-package-devel mailing list