这就是我在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
套接字,但这仍然没有回答我的问题。如果你不能对套接字做任何事情,有什么理由可以使用它?
我的高级编程偏见是否会在这里发挥作用?在进行系统级编程时,这种显性是否是常态?
答案 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 ()