I'm trying to write an R program that maintains a socket connection between two different machines and, while that socket for text communication is open, opens a second socket to transfer a file. However, this doesn't seem to work across two separate machines.
To test this, I wrote this basic example:
test-server.R
textSocket <- socketConnection(host="192.168.56.101", port=9998, blocking=TRUE, server=TRUE, encoding="utf-8", timeout=300, open="r+")
fileSize <- as.integer(readLines(textSocket, 1))
binSocket <- socketConnection(host="192.168.56.101", port=9999, blocking=TRUE, server=TRUE, timeout=15, open="rb")
fileData <- readBin(binSocket, "raw", n=fileSize)
close(binSocket)
outFile <- file("fromClient.txt", open="wb")
writeBin(fileData, outFile)
close(outFile)
close(textSocket)
test-client.R
textSocket <- socketConnection(host="192.168.56.101", port=9998, server=FALSE, blocking=TRUE, encoding="utf-8", timeout=86400, open="r+")
fileSize <- as.integer(file.info("toServer.txt")$size)
writeLines(toString(fileSize), textSocket)
inFile <- file("toServer.txt", open="rb")
fileData <- readBin(inFile, "raw", n=fileSize)
close(inFile)
binSocket <- socketConnection(host="192.168.56.101", port=9999, blocking=TRUE, server=FALSE, timeout=300, open="rb")
writeBin(fileData, binSocket)
close(binSocket)
close(textSocket)
For the sake of brevity, I have removed all the print statements that I used to confirm which specific line was the problem.
If I put both of these files (and toServer.txt) on the machine on "192.168.56.101" and then run both files on two separate R sessions with source(), the whole thing works perfectly. A "fromClient.txt" file appears in my working directory containing exactly what I expected, and no warnings or errors are printed.
However, if I instead run the test-client.R file on a different machine (on 192.168.56.102), then the files execute up until the line where binSocket is created. And then they give me the following errors:
Client side (gives me the error first):
Error in socketConnection(host = "192.168.56.101", port = 9999, blocking = TRUE, :
cannot open the connection
In addition: Warning message:
In socketConnection(host = "192.168.56.101", port = 9999, blocking = TRUE, :
192.168.56.101:9999 cannot be opened
Server side
Error in socketConnection(host = "192.168.56.101", port = 9999, blocking = TRUE, :
cannot open the connection
In addition: Warning message:
In socketConnection(host = "192.168.56.101", port = 9999, blocking = TRUE, :
problem in listening on this socket
(For context, both of these are virtual machines on the Virtualbox "host only network" setting. Both machines are running Ubuntu 22 with R and R studio installed. Also, there are no processes running on ports 9998 or 9999, I can change those and I still get this issue.)
So what gives? Does R just not allow sessions to create two simultaneous sockets? I couldn't find anything like that mentioned in the docs or in any other threads, though in fairness there don't seem to be many people doing socket work with base R.
UPDATE: So I still don't think it's possible to have two sockets open, but as it turns out, I don't need that to send files alongside text! If I open the main socket (textSocket in the code) with the parameter open="r+b", then I can send both text and binary data across the socket. I can use readLines(), writeLines(), readBin(), and writeBin(), all on the same socket as long as I'm keeping track of sizes.