Created
June 15, 2012 15:38
-
-
Save chrisdew/2937090 to your computer and use it in GitHub Desktop.
A working client to server sending of a message in protobuf format.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Network.Socket hiding (send, sendTo, recv, recvFrom) | |
import Network.Socket.ByteString | |
import qualified Data.ByteString.Lazy as LBS | |
import qualified Data.ByteString as BS | |
import Text.ProtocolBuffers.WireMessage (messageGet) | |
import AddressBookProtos.Person | |
main :: IO () | |
main = do | |
withSocketsDo $ do | |
sock <- socket AF_INET Datagram 0 | |
bindSocket sock (SockAddrInet 4567 iNADDR_ANY) | |
socketRx sock | |
mesgToPerson :: LBS.ByteString -> Either String (Person, LBS.ByteString) | |
mesgToPerson mesg = messageGet mesg | |
strictToLazyBS :: BS.ByteString -> LBS.ByteString | |
strictToLazyBS x = LBS.fromChunks [x] | |
socketRx :: Socket -> IO () | |
socketRx sock = do | |
putStrLn "waiting for packet" | |
(mesg, _) <- Network.Socket.ByteString.recvFrom sock 1500 | |
putStrLn "received packet" | |
putStrLn "-------------------" | |
putStrLn $ show mesg | |
putStrLn "-------------------" | |
let eitherPerson = mesgToPerson (strictToLazyBS mesg) | |
case eitherPerson of | |
Right (person, _) -> putStrLn $ show person | |
Left err -> (putStrLn "Failed to parse.") >> (putStrLn err) | |
putStrLn "-------------------" | |
socketRx sock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main where | |
import Network.Socket hiding (send, sendTo, recv, recvFrom) | |
import Network.Socket.ByteString | |
import Text.ProtocolBuffers.Header (uFromString) | |
import Text.ProtocolBuffers.WireMessage (messagePut) | |
import Data.ByteString as BS | |
import Data.ByteString.Lazy as LBS | |
import Data.Sequence (fromList) | |
import AddressBookProtos.Person | |
import AddressBookProtos.Person.PhoneNumber | |
import AddressBookProtos.Person.PhoneType | |
opensocket :: HostName -> String -> IO (Socket, AddrInfo) | |
opensocket hostname port = | |
do -- Look up the hostname and port. Either raises an exception | |
-- or returns a nonempty list. First element in that list | |
-- is supposed to be the best option. | |
addrinfos <- getAddrInfo Nothing (Just hostname) (Just port) | |
let serveraddr = Prelude.head addrinfos | |
-- Establish a socket for communication | |
sock <- socket (addrFamily serveraddr) Datagram defaultProtocol | |
-- Save off the socket, and server address in a handle | |
return (sock, serveraddr) | |
john :: Person | |
john = Person { | |
AddressBookProtos.Person.id = 1234, | |
name = uFromString "John Doe", | |
email = Just $ uFromString "[email protected]", | |
phone = fromList [ | |
PhoneNumber { | |
number = uFromString "555-4321", | |
type' = Just HOME | |
} | |
] | |
} | |
johnLBS :: LBS.ByteString | |
johnLBS = messagePut john | |
lazyToStrictBS :: LBS.ByteString -> BS.ByteString | |
lazyToStrictBS x = BS.concat $ LBS.toChunks x | |
main::IO() | |
main = do (sock, addr) <- opensocket "localhost" "4567" | |
_ <- sendTo sock (lazyToStrictBS johnLBS) (addrAddress addr) | |
return () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment