Keep tests that open sockets and otherwise interact with resources not controlled by the test environment itself separately, what most people like to call integration tests. Only those cannot be cached - and it's a huge trade off and while you get a lot of value from those tests, exactly because they can't be cached, you want to keep those to a minimum.
Certainly, you can optimize some of your tests by caching them! But they should be fast anyway, because your software should be fast. The software I currently work on has massive test suites containing around 50k tests that run in about 3 minutes per suite on my PC. It's time consuming, I suppose, but caching would mean that I'm not actually flushing out latent bugs. Instead, we run all of the tests every time and do things like randomize the execution order, so we find bugs before customers do.
At the point where your software interacts with threads (or the kernel!) you've already brought in non-determinism and trying to act like your tests are really deterministic is naive.
Learn to separate tests that use outside resources and behave undeterminastically from the ones that are never flaky, make sure to cache the latter. If you don't do that you're still in the dark ages of testing when tests are a pain to touch and fail all the time for no reason.
I've also rarely ever touched software that is actually free of nondeterminism, so I am deeply skeptical of caching anything but the simplest test case. And those are fast.
Mock the entire socket API, so you're not actually testing your software?
At the end of the day you need to run some tests with external interactions, and you shouldn't cache those.
Also keep in mind any time you perform syscalls, you have external interactions. Their behavior could change and you want to know if they have intermittent failure scenarios. Using threads? You're nondeterministic, you should keep running tests.
Then the destination of that socket should be managed by the test too.
For example: https://pkg.go.dev/net/http/httptest#Server