[Cuis-dev] finding an open port

Martin McClure martin at hand2mouse.com
Sat Oct 26 20:15:42 PDT 2024


If you're just listening on an unused port for a test case, what would 
usually be done is to let the OS pick an open port for you. This is 
known as an ephemeral port or a sometimes a wildcard port.

I don't know exactly how to do this in Cuis, but hopefully the VM used 
by Cuis allows you to do this. Typical APIs let you specify an ephemeral 
port by specifying 0 as the port number, and then provide some way to 
find what port number the system decided to use.

Regards,

-Martin

On 10/25/24 06:35, Mark Volkmann via Cuis-dev wrote:
> I should have explained my use case. I'm using this in the setUp 
> method for an SUnit test. It tests the endpoints of a web server. 
> Previously the setUp method always started the server on a specific 
> port. If that port was in use then the tests would fail. Now it always 
> finds an available port and the tests pass regardless of whether 
> specific ports are in use. If anyone is curious, you can see the code 
> for the setUp and tearDown methods here: 
> https://github.com/mvolkmann/Cuis-Smalltalk-WebClientPlus/blob/3eea948bc803aad814cc18932d7c57d45188b031/WebClientPlus.pck.st#L101
>
> On Fri, Oct 25, 2024 at 8:30 AM Jon Raiford <raiford at labware.com> wrote:
>
>     I think you are much better off grabbing the latest vm and using
>     the listenOn: code with an exception handler. Connecting to your
>     machine in a loop seems to be a backwards way to look for an
>     unused port.
>
>     Jon
>
>     *From: *Mark Volkmann <r.mark.volkmann at gmail.com>
>     *Date: *Thursday, October 24, 2024 at 8:01 PM
>     *To: *Discussion of Cuis Smalltalk <cuis-dev at lists.cuis.st>
>     *Cc: *Jon Raiford <raiford at labware.com>, Gerald Klix <cuis.01 at klix.ch>
>     *Subject: *Re: [Cuis-dev] finding an open port
>
>     I landed on a solution that seems to work fine. Does this seem
>     reasonable?
>
>     When I pass this 3000 and port 3000 is in use, it returns 3001.
>
>     openPortFrom: aNumber
>         | hostAddress port socket |
>
>     hostAddress := NetNameResolver addressForName: 'localhost'.
>     port := aNumber.
>     socket := Socket newTCP.
>
>     [ true ] whileTrue: [
>     [
>
>     socket connectTo: hostAddress port: port waitForConnectionFor: 1.
>
>     socket disconnect.
>
>     port := port + 1.
>
>     ] on: ConnectionTimedOut do: [ :ex | ^ port ].
>
>     ].
>
>     On Thu, Oct 24, 2024 at 11:45 AM Jon Raiford via Cuis-dev
>     <cuis-dev at lists.cuis.st> wrote:
>
>         For what it’s worth, the way I looked at his code was that the
>         “listenOn: port” should have thrown an RTE as the OS knows
>         immediately that the port is not available. Of course Mark’s
>         code below doesn’t handle errors there, but that would have
>         been resolved during debugging. Whether or not the rest of the
>         code is sane is another matter entirely 😊.
>
>         Jon
>
>         *From: *Cuis-dev <cuis-dev-bounces at lists.cuis.st> on behalf of
>         Gerald Klix via Cuis-dev <cuis-dev at lists.cuis.st>
>         *Date: *Thursday, October 24, 2024 at 12:25 PM
>         *To: *cuis-dev at lists.cuis.st <cuis-dev at lists.cuis.st>
>         *Cc: *Gerald Klix <cuis.01 at klix.ch>
>         *Subject: *Re: [Cuis-dev] finding an open port
>
>         Dear Mark,
>
>         why in name of Alan (Perlis) do you expect a connection to
>         your newly
>         created server socket pop out of nowhere?
>
>         Increase the time out to 60 in `connected := socket
>         waitForConnectionFor: 1 ifTimedOut: [ false ].`,
>         send the #openPortFrom: message to your object.
>
>         Switch to Terminal window, and start telnet like this
>         `telnet 127.0.0.1 <http://127.0.0.1> 3000` and marvel at the
>         results.
>
>         Sorry for my harsh words: This issue has nothing to do with Cuis,
>         but a lot with socket, bind and listen.
>
>         See man 2 bind, man 2 listen
>
>
>         Just my 0,01€,
>
>         Gerald
>
>
>
>         On 10/24/24 2:29 AM, Mark Volkmann via Cuis-dev wrote:
>         > I wrote the following code to take a port number and return
>         the first port
>         > starting from that number that is open. For example, if
>         ports 3000 and 3001
>         > are in use and I send "MyClass openPortFrom: 3000" then I
>         expect it to
>         > return 3002. Can you spot why this never finds an open port
>         and loops
>         > forever?
>         >
>         > openPortFrom: aNumber
>         > | connected port socket |
>         >
>         > connected := false.
>         > port := aNumber.
>         >
>         > [ connected ] whileFalse: [
>         > 'trying port {1}' format: { port } :: print.
>         > socket := Socket newTCP.
>         > socket listenOn: port.
>         > connected := socket waitForConnectionFor: 1 ifTimedOut: [
>         false ].
>         > connected ifTrue: [socket disconnect] ifFalse: [ port :=
>         port + 1 ].
>         > ].
>         >
>         > ^port.
>         >
>         >
>
>         -- 
>         Cuis-dev mailing list
>         Cuis-dev at lists.cuis.st
>         https://lists.cuis.st/mailman/listinfo/cuis-dev
>
>         -- 
>         Cuis-dev mailing list
>         Cuis-dev at lists.cuis.st
>         https://lists.cuis.st/mailman/listinfo/cuis-dev
>
>
>     -- 
>
>     R. Mark Volkmann
>
>     Object Computing, Inc.
>
>
>
> -- 
> R. Mark Volkmann
> Object Computing, Inc.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20241026/43040cf0/attachment-0001.htm>


More information about the Cuis-dev mailing list