[R] Finding an available port for server socket

From: <jhallman_at_frb.gov>
Date: Fri 15 Apr 2005 - 07:54:54 EST


I've written a Smalltalk application which starts R on another machine and then communicates with it via sockets. The functions involved are:

slaveStart <- function(masterHost, masterPort){   inPort <- availablePort()
  sendSocket(as.character(inPort), masterHost, masterPort)   socketSlave(inPort)
}

socketSlave <- function(inPort){
  ## listens on inPort.
  on.exit(closeAllConnections(), add = T)   repeat {
    inConn <- socketConnection(port = inPort, server = T, blocking = T)     try(source(inConn, echo = T, prompt.echo = "> ",

               max.deparse.length = 50000))     close(inConn)
  }
}

sendSocket <- function(strings, host, port){   ## open a blocking client socket, put strings on it, and close   outConn <- socketConnection(host, port, blocking = T)   writeLines(strings, outConn)
  close(outConn)
}

availablePort <- function(){
  ## find a port that R can listen on
  ## just returns 40001 on Windows
  portsInUse <- 0
  os <- as.vector(Sys.info()["sysname"])   if(os == "Linux"){

    hexTcp <- system("cat /proc/net/tcp | awk '{print $2}'", intern = T)
    hexUdp <- system("cat /proc/net/udp | awk '{print $2}'", intern = T)
    portsInUse <- hex2numeric(gsub(".*\:", "", c(hexTcp[-1], hexUdp[-1])))
  }
  if(os == "SunOS"){
    ## use a locally written script that massages output from netstat     portsInUse <- as.numeric(system("/mra/prod/scripts/portsInUse", intern = T))   }
  port <- 40001
  while(!is.na(match(port, portsInUse))) port <- port + 1   port
}

The way this works is that

(i) The Smalltalk app running on firstMachine finds an available port (say

  1. that it can listen on, start listening there, and writes

    slaveStart("firstMachine", 12345)

    to startUpFile.

(ii) The Smalltalk app does something like this to start R on secondMachine:

    ssh secondMachine R < startUpFile > someLogFile

(iii) R sends the inPort port number back to Smalltalk.

(iv) Whenever Smalltalk wants R to do something, it opens a client connection

      to inPort on secondMachine and writes R code to it.  It closes the
      connection when it finishes writing the R code to it.  If Smalltalk
      wants to get a result returned from R, the code sent will include a call
      to sendSocket() to accomplish this.


(v) If Smalltalk expects a reply via sendSocket, it resumes listening on
masterPort for a connection from R.

And so on....

All of this works so far, but my availablePort() function is too ugly, and I don't expect it to work on Windows. So my question is: Is there a better, more portable way I can find an available port? If not, can someone put one in there?

Jeff



R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html Received on Fri Apr 15 08:02:31 2005

This archive was generated by hypermail 2.1.8 : Fri 03 Mar 2006 - 03:31:11 EST