简体   繁体   中英

Exceptions in recursive functions Haskell

I have the following code for a simple web server in Haskell.

module Main where

import Control.Exception
import Control.Monad
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8
import Data.Char
import Network.Socket
import Network.Socket.ByteString (recv, sendAll)
import System.Mem (performGC)

packStr = B.pack . map (fromIntegral . ord)

msg :: String
msg =
    "HTTP/1.1 200 OK\n"
        ++ "Content-Type: text/html\n\n"
        ++ "<html><body><a href=#>download</a></body></html>\n"

manageConnections sock =
    forever
        ( do
            (conn, addr) <- accept sock
            putStrLn $ "Connection from" ++ show addr ++ "\n"
            r <- recv conn 1024
            B.putStr r
            sendAll conn $ packStr msg
            seq id close conn -- for force close the socket the socket
        )

main :: IO ()
main = do
    putStrLn "Starting"
    sock <- socket AF_INET Stream 0
    setSocketOption sock ReuseAddr 1
    bind sock (SockAddrInet 1337 $ tupleToHostAddress (127, 0, 0, 1))
    listen sock 4
    manageConnections sock

As you can see the function manageConnections is where the main thread spends most of the time. My question is how do I handle user interrupts in the manageConnections function ?. What I mean is, if I press Ctrl-C the program would not close the "conn" socket and it would exit. I want to catch the user interrupt and close the socket properly.

if I press Ctrl-C the program would not close the "conn" socket

All file descriptors (including sockets) are closed by the OS when the program finishes its execution.

I want to catch the user interrupt

You might want to try System.Posix.Signals.installHandler .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM