关闭它后,Unix域套接字文件仍然存在

时间:2014-02-09 11:51:11

标签: sockets unix unix-socket

这就是我在ghci(Haskell REPL)中尝试的内容:

>>> import Network.Socket
>>> sock <- socket AF_UNIX Stream defaultProtocol
>>> bind sock (SockAddrUnix "./test.socket")
>>> listen sock 5
>>> close sock

此时./test.socket在文件系统中拒绝连接,但我希望在关闭监听连接后,该文件也将被删除。我相信这是标准的Unix惯例,不是特定于Haskell的,所以在关闭文件后让文件存在的原因是什么?

更新:如果我尝试将另一个套接字绑定到同一个文件,我会收到错误:

>>> sock2 <- socket AF_UNIX Stream defaultProtocol
>>> bind sock (SockAddrUnix "./test.socket")
*** Exception: bind: resource busy (Address already in use)

所以,如果我不能将另一个套接字重新绑定到该文件或重新连接到该文件,因为它已关闭了什么意思?

更新: man entry for unix提及:

  

使用文件名绑定到套接字会在文件系统中创建套接字   当不再需要时,调用者必须删除 (使用   取消链接(2))。通常的UNIX封闭语义适用;插座   可以在任何时候取消链接,最终将被删除   文件系统在关闭它的最后一个引用时。

所以从用户那里可以明确地看到unlink套接字,但这仍然没有回答我的问题。如果你不能对套接字做任何事情,有什么理由可以使用它?

我的高级编程偏见是否会在这里发挥作用?在进行系统级编程时,这种显性是否是常态?

1 个答案:

答案 0 :(得分:0)

我写了这个

createSocket :: FilePath -> IO Socket
createSocket path = do
  removeIfExists path
  sock <- socket AF_UNIX Stream 0
  bind sock $ SockAddrUnix path
  return sock

removeIfExists :: FilePath -> IO ()
removeIfExists fileName = removeLink fileName `catch` handleExists
  where handleExists e
          | isDoesNotExistError e = return ()
          | otherwise = throwIO e

更新:关闭套接字:

closeSocket :: Socket -> IO ()
closeSocket sock = do
  name <- getSocketName sock
  close sock
  case name of
    SockAddrUnix path -> removeIfExists path
    _ -> return ()