I don't understand your use case, why does the client have access to the license server? Doesn't that defeat the point?
Actually, not at all. As already mentioned, especially in the CAD/CAE/CFD field many license models work like that (e.g. StarCCM+, Flowtech Shipflow, NUMECA tools). You get a license issued to a server and several clients can connect to it. FlexLM is a great (and most commonly) used program to achieve that.
Back to the OP...
I assume FlexLM is no option for you. If we are talking about a software where each license is worth a couple of thousands dollars (or euros or the equivalent value in any other currency), then I'd say looking into professional solutions for this problem is definitely worth it. Again (as I am working in the CAD/CFD field and have good experience with it) FlexLM would be a very good option in that case.
Now, if you really want/need to roll your own:
Having a server application with non-configurable ports is a no-go imho.
First of all, (of course) the floating license needs to be node locked to the server it runs on. I assume that's a given, but I'd still like to stress it. HDD-serials and MAC-addresses are good candidates for that. They are easy to get from the OS and rarely change. Limiting the license to the OS is also a good way to go, to avoid "cracking" your license using parallels, for example.
To circumvent the problem of having multiple servers on the same machine I would take a shared memory approach. I don't know what language your server is in, but for C++ the boost interprocess library offers a ncie API.
I'd generate a signature based on the hardware infos stored in the license (which are neccessary and would prevent the license from working on that particular machine if they were changed) and put that into the shared memory. Then have every instance of the server access that shared memory and look for that signature. If it's there, the license is in use and cannot be used again. If it isn't, store the signature in the shared memory which locks it for other instances of the server.
About the VM thing... Sure if the original license was issued for a VM, it is possible to clone it which would cause the same hardware IDs to be generated and then multiple VMs could run on the same license.
However, for most VMs (VMWare, Virtual Box, for example) there are pretty good methods to detect them. It usually involves using some inline assembler, but google it, and then it's only copy paste ;)
So I would actually put a check in the server (which we do for our software, btw.) to prevent it from running on a VM. You might even put a switch in your license to allow customers that can explain why they want to run the server in a VM to do so (which we do).