开发者

Building and parsing SIP messages (strings) in Haskell

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 a开发者_如何学运维bove 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:1234@someserver.com SIP/2.0\r\n"
  write h "Via: SIP/2.0/TCP 192.168.0.153;branch-z9hg4bK4b1234\r\n"
  write h "To: sip:1234@someserver.com\r\n"
  write h "From: <sip:1234@someserver.com>;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


For your first question: How about concatting the strings and writing them in one single operation? Here's an example:

--instead of
main = do
  h <- connectTo server (PortNumber (fromInteger port))
  hSetBuffering h NoBuffering
  write h "OPTIONS sip:1234@someserver.com SIP/2.0\r\n"
  write h "Via: SIP/2.0/TCP 192.168.0.153;branch-z9hg4bK4b1234\r\n"
  write h "To: sip:1234@someserver.com\r\n"
  write h "From: <sip:1234@someserver.com>;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
main = do
  h <- connectTo server (PortNumber (fromInteger port))
  hSetBuffering h NoBuffering
  write h $ "OPTIONS sip:1234@someserver.com SIP/2.0\r\n"
    ++ "Via: SIP/2.0/TCP 192.168.0.153;branch-z9hg4bK4b1234\r\n"
    ++ "To: sip:1234@someserver.com\r\n"
    ++ "From: <sip:1234@someserver.com>;tag=1234\r\n"
    ++ "CSeq: 1 OPTIONS\r\n"
    ++ "Call-ID: abcdefgh\r\n"
    ++ "Content-Length: 0\r\n\r\n"
  listen h

And about the parrsing: Try Parsec for this.

PS: Doing IO with usual Strings is a bit slow. Try ByteString and attoparsec instead.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜