1

I have a cross-platform Golang application which listens on a Unix file socket as follows:

    listener, err := net.Listen("unix", socketFilePath)
    if err != nil {
        return err
    }

When this code runs in Windows (Win10 22H2, specifically), it sometimes fails because another process is already listening on that socket:

listen unix [my socket path]: bind: Only one usage of each socket address 
(protocol/network address/port) is normally permitted.

How do I find which process already is already bound to the socket? I've already verified that no instances of my application's process are running.

My searching led me to various things about open file handles and open network sockets, but AFAICT Windows treats file sockets differently than either of those, so those tools and techniques don't reveal the thing I'm looking for.

Things that didn't solve my problem:

JakeRobb
  • 162
  • 1
    Why isn’t your code encapsulated in a try statement? This seems more like a Stack Overflow question. So what’s the end goal, open the socket successfully, or determine which process has the open socket on that particular port? – Ramhound Oct 20 '23 at 19:17
  • This post might explain that the port is probably open by a previous zombie instance of your own program. Check if the answers in it apply here. – harrymc Oct 20 '23 at 19:29
  • @harrymc that post is about TCP ports. This is about file sockets. As noted in the question, I tried multiple ways of finding ports in use; they revealed TCP ports but not file sockets. – JakeRobb Oct 22 '23 at 00:21
  • @Ramhound Go does not have exceptions and try statements; commands return errors. Regardless, I’m not trying to fix the code; I’m trying to learn how to do a thing with Windows. I thought SuperUser was more appropriate. – JakeRobb Oct 22 '23 at 01:43

2 Answers2

3

How do I find which process already is already bound to the socket? I've already verified that no instances of my application's process are running.

Your error message is cross-platform as well. Even if the process exits, 'Unix' file-based sockets are not deleted automatically; the process itself is responsible for the unlink() that must be done before a new bind/listen is attempted. Manually deleting the socket should allow you to listen on it again.

u1686_grawity
  • 452,512
  • 1
    Thank you. The term “unlink” is what I needed; that led me here: https://stackoverflow.com/questions/16681944/how-to-reliably-unlink-a-unix-domain-socket-in-go-programming-language/16702173#16702173 – JakeRobb Oct 22 '23 at 00:52
  • So, the real answer to my question is this: there is no process holding the file socket open, so there’s no way to find said nonexistent process. My process simply never unlinked it. After the fact, I can make it available again by deleting the file, and probably also by rebooting, but the real solution is to ensure that my process calls unlink before it exits. – JakeRobb Oct 22 '23 at 00:55
  • 1
    "Unlink" is just the usual Unix-like function for removing a file, and this applies to file-like sockets as well. – u1686_grawity Oct 22 '23 at 09:49
0

How do I find which process already is already bound to the socket? I've already verified that no instances of my application's process are running.

Use SysInternals TcpView tool.

fpiette
  • 176
  • I can’t try it for myself until Monday, but in the meantime: the docs say it works for TCP and UDP. I al looking for file sockets. Do you know for a fact that this works for file sockets? – JakeRobb Oct 22 '23 at 00:25
  • In Windows (I mean at the OS level, not at the programming language level), there is no such thing as "file socket". There are "files" and "sockets". Sysinternals TCPView will show you socket activity. Use Sysinternals ProcessMonitor to see file activity (and much more). – fpiette Oct 22 '23 at 07:00