Это для будущих новых хаскелеров.
Я основал свой код на этом примере .
Я сделал улучшения, основанные на этой ветке reddit и предложениях, сделанных выше. Операторы импорта все еще неаккуратны, но их исправление оставлено как общеизвестное «упражнение для читателя». Я приглашаю любые дополнительные предложения, ведущие к улучшениям.
import Network.Socket
import Control.Monad
import Network
import System.Environment (getArgs)
import System.IO
import Control.Concurrent (forkIO)
main :: IO ()
main = withSocketsDo $ do
[portStr] <- getArgs
sock <- socket AF_INET Stream defaultProtocol
let port = fromIntegral (read portStr :: Int)
socketAddress = SockAddrInet port 0000
bindSocket sock socketAddress
listen sock 1
putStrLn $ "Listening on " ++ (show port)
sockHandler sock
sockHandler :: Socket -> IO ()
sockHandler sock' = forever $ do
(sock, _) <- Network.Socket.accept sock'
handle <- socketToHandle sock ReadWriteMode
hSetBuffering handle NoBuffering
forkIO $ commandProcessor handle
commandProcessor :: Handle -> IO ()
commandProcessor handle = forever $ do
line <- hGetLine handle
let (cmd:arg) = words line
case cmd of
"echo" -> echoCommand handle arg
"add" -> addCommand handle arg
_ -> do hPutStrLn handle "Unknown command"
echoCommand :: Handle -> [String] -> IO ()
echoCommand handle arg = do
hPutStrLn handle (unwords arg)
addCommand :: Handle -> [String] -> IO ()
addCommand handle [x,y] = do
hPutStrLn handle $ show $ read x + read y
addCommand handle _ = do
hPutStrLn handle "usage: add Int Int"