haskell http 服务器的 acceptFork
haskell acceptFork for http server
我必须在 haskell 中创建一个 http 服务器。为此,我必须定义一个 acceptFork 函数来处理传入的 TCP 连接,它具有以下类型:
acceptFork :: Socket -> (Handle -> IO ()) -> IO ()
其工作方式如下:
- 使用 accept 函数接受传入连接,其中 returns 一个 Handle
- 使用 hSetBuffering 函数禁用缓冲(将值设置为 NoBuffering)
- 使用 hSetNewlineMode 函数设置新行字符(使用参数 (NewlineMode CRLF CRLF))
- 启动一个对句柄值运行输入操作的新线程
- 递归等待下一个连接
到目前为止我想到的是:
import qualified Network.Socket as NS
acceptFork :: Socket -> (Handle -> IO ()) -> IO ()
acceptFork lsock k = do
(csock,_) <- NS.accept lsock
hSetBuffering lsock NoBuffering
hSetNewlineMode lsock (NewlineMode CRLF CRLF)
forkIO (k csock)
问题是它甚至无法编译。有人可以解释我做错了什么吗?谢谢!
这是我得到的错误:
bead2.hs:31:23:
Couldn't match expected type `(Handle -> BufferMode -> IO ())
-> Socket
-> BufferMode
-> (Handle -> NewlineMode -> IO ())
-> Socket
-> NewlineMode
-> IO (Handle, t0)'
with actual type `IO (Socket, NS.SockAddr)'
The function `NS.accept' is applied to 7 arguments,
but its type `Socket -> IO (Socket, NS.SockAddr)' has only one
In a stmt of a 'do' block:
conn@(csock, _) <- NS.accept
lsock
hSetBuffering
lsock
NoBuffering
hSetNewlineMode
lsock
(NewlineMode CRLF CRLF)
In the expression:
do { conn@(csock, _) <- NS.accept
lsock
hSetBuffering
lsock
NoBuffering
hSetNewlineMode
lsock
(NewlineMode CRLF CRLF);
forkIO (k csock) }
bead2.hs:34:5:
Couldn't match type `ThreadId' with `()'
Expected type: IO ()
Actual type: IO ThreadId
In a stmt of a 'do' block: forkIO (k csock)
In the expression:
do { conn@(csock, _) <- NS.accept
lsock
hSetBuffering
lsock
NoBuffering
hSetNewlineMode
lsock
(NewlineMode CRLF CRLF);
forkIO (k csock) }
好的,我复制了你的内容并添加了缺失的部分(网络 > 2.6 和 < 2.7):
import qualified Network.Socket as NS
import System.IO (Handle, hSetBuffering, hSetNewlineMode, BufferMode(..), Newline(..), NewlineMode(..), IOMode(..))
import Control.Concurrent (forkIO, ThreadId)
acceptFork :: NS.Socket -> (Handle -> IO ()) -> IO ThreadId
acceptFork lsock k = do
(csock,_) <- NS.accept lsock
hsock <- NS.socketToHandle csock ReadWriteMode
hSetBuffering hsock NoBuffering
hSetNewlineMode hsock (NewlineMode CRLF CRLF)
forkIO (k hsock)
基本上你有:
- 大量缺失进口
- 需要通过
NS.socketToHandle
从套接字中获取句柄
- 注意
forkIO
的结果(新线程的 id)
这个编译在:
base >=4.8 && <4.9, network >=2.6 && <2.7
免责声明
我没有没有 运行这个代码所以我不知道它是否有效 - 但它会编译(在我的系统上;))
没有ThreadId
:
只需更改签名和最后一行:
acceptFork :: NS.Socket -> (Handle -> IO ()) -> IO ()
acceptFork lsock k = do
-- ... same as above
_ <- forkIO (k hsock)
return ()
分叉并等待下一个连接:
只需递归调用acceptFork
acceptFork :: NS.Socket -> (Handle -> IO ()) -> IO ()
acceptFork lsock k = do
(csock,_) <- NS.accept lsock
hsock <- NS.socketToHandle csock ReadWriteMode
hSetBuffering hsock NoBuffering
hSetNewlineMode hsock (NewlineMode CRLF CRLF)
_ <- forkIO (k hsock)
acceptFork lsock k
或使用forever
...
import Control.Monad (forever)
acceptFork :: NS.Socket -> (Handle -> IO ()) -> IO ()
acceptFork lsock k = ...
acceptAll :: NS.Socket -> (Handle -> IO ()) -> IO ()
acceptAll sock = forever . acceptFork sock
我必须在 haskell 中创建一个 http 服务器。为此,我必须定义一个 acceptFork 函数来处理传入的 TCP 连接,它具有以下类型:
acceptFork :: Socket -> (Handle -> IO ()) -> IO ()
其工作方式如下:
- 使用 accept 函数接受传入连接,其中 returns 一个 Handle
- 使用 hSetBuffering 函数禁用缓冲(将值设置为 NoBuffering)
- 使用 hSetNewlineMode 函数设置新行字符(使用参数 (NewlineMode CRLF CRLF))
- 启动一个对句柄值运行输入操作的新线程
- 递归等待下一个连接
到目前为止我想到的是:
import qualified Network.Socket as NS
acceptFork :: Socket -> (Handle -> IO ()) -> IO ()
acceptFork lsock k = do
(csock,_) <- NS.accept lsock
hSetBuffering lsock NoBuffering
hSetNewlineMode lsock (NewlineMode CRLF CRLF)
forkIO (k csock)
问题是它甚至无法编译。有人可以解释我做错了什么吗?谢谢!
这是我得到的错误:
bead2.hs:31:23:
Couldn't match expected type `(Handle -> BufferMode -> IO ())
-> Socket
-> BufferMode
-> (Handle -> NewlineMode -> IO ())
-> Socket
-> NewlineMode
-> IO (Handle, t0)'
with actual type `IO (Socket, NS.SockAddr)'
The function `NS.accept' is applied to 7 arguments,
but its type `Socket -> IO (Socket, NS.SockAddr)' has only one
In a stmt of a 'do' block:
conn@(csock, _) <- NS.accept
lsock
hSetBuffering
lsock
NoBuffering
hSetNewlineMode
lsock
(NewlineMode CRLF CRLF)
In the expression:
do { conn@(csock, _) <- NS.accept
lsock
hSetBuffering
lsock
NoBuffering
hSetNewlineMode
lsock
(NewlineMode CRLF CRLF);
forkIO (k csock) }
bead2.hs:34:5:
Couldn't match type `ThreadId' with `()'
Expected type: IO ()
Actual type: IO ThreadId
In a stmt of a 'do' block: forkIO (k csock)
In the expression:
do { conn@(csock, _) <- NS.accept
lsock
hSetBuffering
lsock
NoBuffering
hSetNewlineMode
lsock
(NewlineMode CRLF CRLF);
forkIO (k csock) }
好的,我复制了你的内容并添加了缺失的部分(网络 > 2.6 和 < 2.7):
import qualified Network.Socket as NS
import System.IO (Handle, hSetBuffering, hSetNewlineMode, BufferMode(..), Newline(..), NewlineMode(..), IOMode(..))
import Control.Concurrent (forkIO, ThreadId)
acceptFork :: NS.Socket -> (Handle -> IO ()) -> IO ThreadId
acceptFork lsock k = do
(csock,_) <- NS.accept lsock
hsock <- NS.socketToHandle csock ReadWriteMode
hSetBuffering hsock NoBuffering
hSetNewlineMode hsock (NewlineMode CRLF CRLF)
forkIO (k hsock)
基本上你有:
- 大量缺失进口
- 需要通过
NS.socketToHandle
从套接字中获取句柄
- 注意
forkIO
的结果(新线程的 id)
这个编译在:
base >=4.8 && <4.9, network >=2.6 && <2.7
免责声明
我没有没有 运行这个代码所以我不知道它是否有效 - 但它会编译(在我的系统上;))
没有ThreadId
:
只需更改签名和最后一行:
acceptFork :: NS.Socket -> (Handle -> IO ()) -> IO ()
acceptFork lsock k = do
-- ... same as above
_ <- forkIO (k hsock)
return ()
分叉并等待下一个连接:
只需递归调用acceptFork
acceptFork :: NS.Socket -> (Handle -> IO ()) -> IO ()
acceptFork lsock k = do
(csock,_) <- NS.accept lsock
hsock <- NS.socketToHandle csock ReadWriteMode
hSetBuffering hsock NoBuffering
hSetNewlineMode hsock (NewlineMode CRLF CRLF)
_ <- forkIO (k hsock)
acceptFork lsock k
或使用forever
...
import Control.Monad (forever)
acceptFork :: NS.Socket -> (Handle -> IO ()) -> IO ()
acceptFork lsock k = ...
acceptAll :: NS.Socket -> (Handle -> IO ()) -> IO ()
acceptAll sock = forever . acceptFork sock