用于http服务器的haskell acceptFork(haskell acceptFork for http server)

编程入门 行业动态 更新时间:2024-10-19 20:22:15
用于http服务器的haskell acceptFork(haskell acceptFork for http server)

我必须在haskell中创建一个http服务器。 为此,我必须定义一个acceptFork函数来处理传入的TCP连接,它具有以下类型:

acceptFork :: Socket -> (Handle -> IO ()) -> IO ()

这应该如何工作的方式如下:

使用accept函数接受传入连接,返回Handle 使用hSetBuffering函数禁用缓冲(将值设置为NoBuffering) 使用hSetNewlineMode函数设置新行char(使用参数(NewlineMode CRLF CRLF)) 启动一个新的线程,它在句柄值上运行输入操作 recurisvely等待下一个连接

到目前为止我想出的是:

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) }

I have to create a http server in haskell. For this I have to define an acceptFork function which handles the incoming TCP connections, which has the following type:

acceptFork :: Socket -> (Handle -> IO ()) -> IO ()

The way how this should work is the following:

use the accept function to accept an incoming connection, which returns a Handle disable buffering with hSetBuffering function (set value to NoBuffering) set new line char with hSetNewlineMode function (use parameter (NewlineMode CRLF CRLF)) start a new thread which runs the input action on the handle value recurisvely wait for the next connection

What I've came up with so far is this:

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)

The problem is that it doesn't even compile. Can someone please explain what I'm doing wrong? Thanks!

This is the error that I get:

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 ()

fork并等待下一个连接:

只需递归调用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

ok, I copied what you have and added the missing parts (for network > 2.6 and < 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)

basically you have:

lot's of missing imports need to get the handle from the socket via NS.socketToHandle watch out for the result of forkIO (the new thread's id)

this compiles under:

base >=4.8 && <4.9, network >=2.6 && <2.7

disclaimer

I did not run this code so I have no clue if it works - but it will compile (on my system ;) )

without ThreadId:

just change the signature and last lines:

acceptFork :: NS.Socket -> (Handle -> IO ()) -> IO () acceptFork lsock k = do -- ... same as above _ <- forkIO (k hsock) return ()

fork and wait for the next connection:

just call acceptFork recursively

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

or use 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

更多推荐

本文发布于:2023-07-23 18:35:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1235632.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:服务器   http   haskell   server   acceptFork

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!