gpt4 book ai didi

haskell - 简单的 TCP 客户端

转载 作者:行者123 更新时间:2023-12-04 15:22:24 24 4
gpt4 key购买 nike

我正在尝试在 Haskell 中实现简单的 TCP 客户端。但是一旦连接它就会关闭。我不知道是什么导致它关闭。我怎样才能让它从服务器打印行到 stdout并从 stdin 发送线路永久服务器直到 stdin接收行“:退出”?

import Control.Monad (forever)
import Network (withSocketsDo, PortID(..), connectTo)
import System.IO
import Control.Concurrent (forkFinally)
import Control.Concurrent.Async (race)

main :: IO ()
main = withSocketsDo $ do
-- connect to my local tcp server
handle <- connectTo "192.168.137.1" (PortNumber 44444)
-- should close the connection using handle after everything is done
_ <- forkFinally (talk handle) (\_ -> hClose handle)
return ()

talk :: Handle -> IO ()
talk handle = do
hSetNewlineMode handle universalNewlineMode
hSetBuffering handle LineBuffering
-- if either one of them terminates, other one will get terminated
_ <- race (interactWithServer handle) (interactWithUser handle)
return ()

interactWithServer :: Handle -> IO ()
interactWithServer handle = forever $ do
line <- hGetLine handle
print line -- print a line that came from server into stdout

interactWithUser :: Handle -> IO ()
interactWithUser handle = do
line <- getLine
case line of
":quit" -> return () -- stop loop if user input is :quit
_ -> do hPutStrLn handle line
interactWithUser handle -- send, then continue looping

最佳答案

Ørjan Johansen的帮助我想通了。 forkFinally正在创建一个线程,然后在该主线程关闭之后。那条线本来是要等到talk完成然后关闭连接。它必须是(也缩短了它)

main :: IO ()
main = withSocketsDo $ do
handle <- connectTo "192.168.137.1" (PortNumber 44444)
talk handle `finally` hClose handle

talk :: Handle -> IO ()
talk handle = do
hSetNewlineMode handle universalNewlineMode
hSetBuffering handle LineBuffering
_ <- race fromServer toServer
return ()
where
fromServer = forever $ do
line <- hGetLine handle
print line
toServer = do
line <- getLine
case line of
-- server accepts /quit as disconnect command so better send it to the server
":quit" -> do hPutStrLn handle "/quit"; return "Quit"
_ -> do hPutStrLn handle line; toServer

我希望这段代码是安全的:D

关于haskell - 简单的 TCP 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25226648/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com