Haskell中ByteString解析和网络IO的混合 背景
我正在尝试为二进制网络协议编写一个客户端。 所有网络操作都是通过单个TCP连接执行的,因此从这个意义上讲 来自服务器的输入是一个连续的字节流。 然而,在应用层,服务器从概念上在服务器上发送数据包 流,并且客户机一直在读取,直到它知道已经收到数据包为止 在发送其自己的响应之前,请将其作为一个整体 完成这项工作所需的大量工作包括解析和生成 二进制数据,我正在使用data.Serialize模块 问题 服务器通过TCP流向我发送一个“数据包”。 数据包不一定由换行符终止,也不是预定的 尺寸。 它确实由预定数量的字段组成,字段通常从 用一个4字节的数字描述该字段的长度。 在Data.Serialize的帮助下,我已经有了解析ByteString的代码 将此数据包的版本转换为更易于管理的类型 我希望能够使用以下属性编写一些代码:Haskell中ByteString解析和网络IO的混合 背景,haskell,Haskell,我正在尝试为二进制网络协议编写一个客户端。 所有网络操作都是通过单个TCP连接执行的,因此从这个意义上讲 来自服务器的输入是一个连续的字节流。 然而,在应用层,服务器从概念上在服务器上发送数据包 流,并且客户机一直在读取,直到它知道已经收到数据包为止 在发送其自己的响应之前,请将其作为一个整体 完成这项工作所需的大量工作包括解析和生成 二进制数据,我正在使用data.Serialize模块 问题 服务器通过TCP流向我发送一个“数据包”。 数据包不一定由换行符终止,也不是预定的 尺寸。 它确实由
导入网络
导入系统.IO
将限定的Data.ByteString.Lazy作为L导入
导入数据。序列化
数据MyType
实例序列化MyType
main=带库存的订单$do
您的解析器出了问题,它太急切了。由于某种原因,它很可能需要消息后面的下一个字节hGetContents
frombytestring
不会阻止等待整个区块。它在内部使用hGetSome
我创建了一个简单的测试用例。服务器每秒发送一次“hello”:
import Control.Concurrent
import System.IO
import Network
port :: Int
port = 1234
main :: IO ()
main = withSocketsDo $ do
s <- listenOn $ PortNumber $ fromIntegral port
(h, _, _) <- accept s
let loop :: Int -> IO ()
loop 0 = return ()
loop i = do
hPutStr h "hello"
threadDelay 1000000
loop $ i - 1
loop 5
sClose s
导入控制。并发
导入系统.IO
导入网络
端口::Int
端口=1234
main::IO()
main=带库存的订单$do
s+1非常好而且令人信服的测试用例。奇怪的是,这不是一个额外的字节,我预计在结束的数据包,而是一个领域在中东,似乎是有问题的…
import Control.Concurrent
import System.IO
import Network
port :: Int
port = 1234
main :: IO ()
main = withSocketsDo $ do
s <- listenOn $ PortNumber $ fromIntegral port
(h, _, _) <- accept s
let loop :: Int -> IO ()
loop 0 = return ()
loop i = do
hPutStr h "hello"
threadDelay 1000000
loop $ i - 1
loop 5
sClose s
import qualified Data.ByteString.Lazy as BSL
import System.IO
import Network
port :: Int
port = 1234
main :: IO ()
main = withSocketsDo $ do
h <- connectTo "localhost" $ PortNumber $ fromIntegral port
bs <- BSL.hGetContents h
BSL.putStrLn bs
hClose h