Я пытаюсь создать клиент-серверную программу, используя сетевую (версия 3.1.1.1) библиотеку Haskell, но при попытке установить sh соединение от клиента к серверу я получаю это исключение *** Исключение: threadWait: неверный аргумент (неверный дескриптор файла) и не знаю, как решить эту проблему.
код:
module PeerToPeer where
import Control.Concurrent (forkFinally)
import qualified Control.Exception as E
import Control.Monad (unless, forever, void)
import qualified Data.ByteString as S
import Network.Socket
import Network.Socket.ByteString (recv, sendAll)
import qualified Data.ByteString.Char8 as C
runServer :: Maybe HostName -> ServiceName -> (Socket -> IO ()) -> IO ()
runServer mhost port process = withSocketsDo $ do
addr <- resolveAddr
E.bracket (open addr) close loop
where
resolveAddr = do
let hints = defaultHints { addrFlags = [AI_PASSIVE], addrSocketType = Stream }
head <$> getAddrInfo (Just hints) mhost (Just port)
open addr = do
sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
setSocketOption sock ReuseAddr 1
withFdSocket sock $ setCloseOnExecIfNeeded
bind sock $ addrAddress addr
listen sock 1024
return sock
loop sock = forever $ do
(clientSocket, clientAddr) <- accept sock
putStrLn "Connection Established"
forkFinally (process sock) (const $ gracefulClose sock 5000)
peerHandler sock = do
msg <- recv sock 1024
putStrLn ("Incoming :" ++ (show msg))
runClient :: HostName -> ServiceName -> (Socket -> IO a) -> IO a
runClient host port client = withSocketsDo $ do
addr <- resolve
E.bracket (open addr) close client
where
resolve = do
let hints = defaultHints {addrSocketType = Stream}
head <$> getAddrInfo (Just hints) (Just host) (Just port)
open addr = do
sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
connect sock $ addrAddress addr
return sock
peerComm sock = do
sendAll sock (C.pack "Hello, world!")
Пробовал:
*Server> runServer Nothing "3000" peerHandler
Connection Established
*** Exception: threadWait: invalid argument (Bad file descriptor)
*Client> runClient "127.0.0.1" "3000" peerComm