所以我想通過 tcp 發送大量的東西,因此我使用 Network.Socket 庫......
首先,我有一個包裝資料型別(例如!):
data Message =
List [Int]
| String String
| END
deriving stock Generic
deriving anyclass Binary
deriving Show
deriving Eq
所以一個正常的作業流程是:
--client
let bytestring = encode $ List [1..1000000] -- Lazzy ByteString
send socket $ toStrict bytestring
--server
Just msg <- recv socket 1024
print $ decode $ fromStrict msg
問題是:我收到以下錯誤:
位置 1017 的 Data.Binary.Get.runGet:沒有足夠的位元組 CallStack(來自 HasCallStack):錯誤,在 binary-0.8.8.0:Data 中的 library/binary/src/Data/Binary/Get.hs:351:5 處呼叫。 Binary.Get ClientProjekt:Network.Socket.sendBuf:資源消失(管道損壞)
雖然
- 只需發送/接收和列印而不在服務器上解碼就可以正常作業。
- encoding -> toStrict -> fromStrict -> 解碼:不通過 tcp 發送作業正常。
那么網路如何處理破壞解碼功能的位元組串呢?
uj5u.com熱心網友回復:
主要問題是recv socket 1024從套接字請求僅 1024 個位元組,因此接收到的訊息被截斷。send實際上也不保證會發送完整的位元組串。你想sendAll改用。
我建議使用sendAlland getContentsfromNetwork.Socket.ByteString.Lazy來避免將惰性位元組串轉換為嚴格的位元組串,并省去手動撰寫recv回圈的麻煩。最小的服務器可能如下所示:
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
import GHC.Generics
import Data.Binary
import Network.Socket
import Network.Socket.ByteString.Lazy
import Prelude hiding (getContents)
data Message = List [Int]
deriving (Generic, Binary)
main = do
let hints = defaultHints
{ addrFlags = [AI_NUMERICHOST, AI_NUMERICSERV]
, addrSocketType = Stream }
addr:_ <- getAddrInfo (Just hints) (Just "127.0.0.1") (Just "8080")
s <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
bind s (addrAddress addr)
listen s 1
(s', _) <- accept s
List xs <- decode <$> getContents s'
close s'
print $ sum xs
匹配的最小客戶端可能如下所示:
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
import GHC.Generics
import Data.Binary
import Network.Socket
import Network.Socket.ByteString.Lazy
data Message = List [Int]
deriving (Generic, Binary)
main = do
let hints = defaultHints
{ addrFlags = [AI_NUMERICHOST, AI_NUMERICSERV]
, addrSocketType = Stream }
addr:_ <- getAddrInfo (Just hints) (Just "127.0.0.1") (Just "8080")
s <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
connect s (addrAddress addr)
sendAll s (encode (List [1..1000000]))
close s
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/462865.html
標籤:哈斯克尔
