Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Haskell program to calculate statistics from a
- -- network simulation trace file, using point-free syntax,
- -- lazy evalutation, and the IO monad.
- -- Ciaran Dunne, Heriot-Watt University 2017
- import System.Environment
- -- Main I/O procedure for analysing trace files
- -- The file path is read from the terminal using getArgs
- -- The entire string of the program is lazily read into 'file'
- -- The numbers required for the output are calculated using functions in the code
- -- Then printed as shown
- main = do
- [path] <- getArgs
- file <- readFile path
- let pkts = createPacketList file
- let totalReceived = (fromIntegral . length . receivedPackets) pkts
- let totalDropped = (length . droppedPackets) pkts
- let totalSent = (fromIntegral . length . sentPackets) pkts
- let totalDequeued = (length . dequeuedPackets) pkts
- let totalOverhead = (length . overhead) pkts
- print ("Dropped Packets: " ++ (show totalDropped))
- print ("Received Packets: " ++ (show totalReceived))
- print ("Sent Packets: " ++ (show totalSent))
- print ("Dequeued Packets: " ++ (show totalDequeued))
- print ("Throughput: " ++ (show (totalReceived * 100 / totalSent)))
- print ("Lost Packets: " ++ (show (totalSent - totalReceived)))
- print ("Overhead: " ++ show totalOverhead)
- -- Data type for a packet, in line with the formatting
- -- of the NS trace files. Deriving the Eq and Show typeclasses
- -- so that we can compare and print packets.
- data Packet = Packet
- {event :: Char,
- time :: Float,
- source :: Int,
- dest :: Int,
- pktType :: String,
- size :: Int,
- flags :: String,
- fid :: Int,
- src_addr :: String,
- dst_addr :: String,
- seq_num :: Int,
- pkt_id :: Int
- }
- deriving (Eq, Show)
- -- A function that takes a list of strings and converts
- -- each element to it's corresponding datatype so they can
- -- be entries for the Packet data constructor.
- -- Takes lists such as:
- -- ["r","0.13","1","2","cbr","1000","-------","2","1.0","3.1","2","2"]
- toPacket :: [String] -> Packet
- toPacket pkt = Packet
- { event = head (pkt !! 0)
- , time = read (pkt !! 1) :: Float
- , source = read (pkt !! 2) :: Int
- , dest = read (pkt !! 3) :: Int
- , pktType = pkt !! 4
- , size = read (pkt !! 5) :: Int
- , flags = pkt !! 6
- , fid = read (pkt !! 7) :: Int
- , src_addr = pkt !! 8
- , dst_addr = pkt !! 9
- , seq_num = read (pkt !! 10) :: Int
- , pkt_id = read (pkt !! 11) :: Int
- }
- --Converts file first into lines, then splits at whitespace
- --then converts each element of each split line into a packet data structure
- --String -> [String] -> [[String]] -> [Packet]
- createPacketList :: String -> [Packet]
- createPacketList = (map toPacket) . (map words) . lines
- -- Allows us to create a function to test the event of a packet
- -- For example:
- -- ev 'd' pkt = True if the event of the pkt is 'd'
- ev :: Char -> Packet -> Bool
- ev = (. event) . (==)
- -- Same as the event function, but for testing event type
- -- For example: ty "ack" pkt = True
- -- if the type of the pkt is an acknowledgement
- ty :: String -> Packet -> Bool
- ty = (. pktType) . (==)
- --Takes a list of packets, and keeps the packets
- --that have the 'd' event
- droppedPackets :: [Packet] -> [Packet]
- droppedPackets = filter (\p -> (ev 'd' p))
- -- Keeps packets that have the 'r' event
- -- and aren't acknowledgements
- receivedPackets :: [Packet] -> [Packet]
- receivedPackets = filter (\p -> (ev 'r' p)&&(not (ty "ack" p)))
- -- Keeps packets that have the '+' event and aren't acknowledgements
- sentPackets :: [Packet] -> [Packet]
- sentPackets = filter (\p -> (ev '+' p)&&(not (ty "ack" p)))
- -- Keeps packets that have the '-' event
- dequeuedPackets :: [Packet] -> [Packet]
- dequeuedPackets = filter (ev '-')
- -- Keeps packets that have the "ack" packet type
- overhead :: [Packet] -> [Packet]
- overhead = filter (ty "ack")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement