[Cuis-dev] finding an open port
Gerald Klix
cuis.01 at klix.ch
Fri Oct 25 06:49:13 PDT 2024
IC, that explains a lot (of the confusion).
Actually you need both methods.
How about the following algorithm?
Use our old code that opens a server socket and modify it like this:
Before waiting for a connection, fork a process that tries to connect to
that port, simulating a web client. Let the client send some magic string
and string representation of both port numbers to the server. The server
than
checks the magic string and the port numbers.
If the ports number agree you can be quite sure
that a connection is possible.
HTH,
Gerald
On 10/25/24 3:35 PM, 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 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.
>>
>
>
More information about the Cuis-dev
mailing list