在 Haskell 中构建和解析 SIP 消息(字符串)
我正在尝试通过编写 SIP 客户端来学习 Haskell。
我的问题是在下面的示例中,构建表示 SIP 请求的字符串的函数是什么样的,或者换句话说,而不是我正在对套接字句柄执行的 9 次写入,我将如何编写一个函数来构建字符串然后通过一次写入发送它?
上述问题的另一面是我如何解析从套接字返回的字符串以解析其中的所有信息。例如,每个 SIP 请求都有一个方法、URI、版本等。我是否应该使用单独的函数一次提取每个项目?
我在该任务中所做的尝试看起来与带有一个大“do”块的命令式代码完全相同,据我所知,这不是功能性的方式。
import Network
import System.Exit
import System.IO
import Text.Printf
server = "127.0.0.1"
port = 5060
main = do
h <- connectTo server (PortNumber (fromInteger port))
hSetBuffering h NoBuffering
write h "OPTIONS sip:[email protected] SIP/2.0\r\n"
write h "Via: SIP/2.0/TCP 192.168.0.153;branch-z9hg4bK4b1234\r\n"
write h "To: sip:[email protected]\r\n"
write h "From: <sip:[email protected]>;tag=1234\r\n"
write h "CSeq: 1 OPTIONS\r\n"
write h "Call-ID: abcdefgh\r\n"
write h "Content-Length: 0\r\n"
write h "\r\n"
listen h
write :: Handle -> String -> IO ()
write h s = do
hPrintf h "%s" s
printf "> %s" s
listen :: Handle -> IO ()
listen h = forever $ do
t <- hGetLine h
let s = init t
putStrLn s
where
forever a = do a; forever a
I'm attempting to learn Haskell by writing a SIP client.
The question I have is in the example below what would a function to build a string representing the SIP request look like, or in other words instead of the 9 writes I'm doing to the socket handle how would I write a function to build the string and then send it with one write?
The flip side of the above question is how would I parse the string I get back from the socket to parse all the information from it. For example each SIP request has a method, URI, version etc. should I extract each item with a separate function one at a time?
The attempts I've made at the task look exactly the same as imperative code with one big "do" block which from what I can tell is not the functional way.
import Network
import System.Exit
import System.IO
import Text.Printf
server = "127.0.0.1"
port = 5060
main = do
h <- connectTo server (PortNumber (fromInteger port))
hSetBuffering h NoBuffering
write h "OPTIONS sip:[email protected] SIP/2.0\r\n"
write h "Via: SIP/2.0/TCP 192.168.0.153;branch-z9hg4bK4b1234\r\n"
write h "To: sip:[email protected]\r\n"
write h "From: <sip:[email protected]>;tag=1234\r\n"
write h "CSeq: 1 OPTIONS\r\n"
write h "Call-ID: abcdefgh\r\n"
write h "Content-Length: 0\r\n"
write h "\r\n"
listen h
write :: Handle -> String -> IO ()
write h s = do
hPrintf h "%s" s
printf "> %s" s
listen :: Handle -> IO ()
listen h = forever $ do
t <- hGetLine h
let s = init t
putStrLn s
where
forever a = do a; forever a
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于您的第一个问题:如何连接字符串并将它们写入一个操作中?这是一个例子:
关于解析:尝试 Parsec 。
PS:使用普通的
String
进行IO有点慢。尝试使用ByteString
和attoparsec
代替。For your first question: How about concatting the strings and writing them in one single operation? Here's an example:
And about the parrsing: Try Parsec for this.
PS: Doing IO with usual
String
s is a bit slow. TryByteString
andattoparsec
instead.