在 Haskell 中读取常量时的字节顺序问题

问题描述 投票:0回答:1

当我运行代码时:

import Control.Applicative
import Control.Concurrent
import Control.Monad
import Network.Socket
import System.Environment
import System.IO
import Numeric (showHex)
import qualified System.ByteOrder as BO
import qualified Data.ByteString as B
import Data.ByteString (toStrict)
import Data.ByteString.Conversion (toByteString)
import Data.Word (Word16)



prettyPrint :: B.ByteString -> String
prettyPrint = concatMap ((\x -> "0x"++x++" ") . flip showHex "") . B.unpack

main :: IO ()
main = withSocketsDo $ do
  port <- toEnum . read . head <$> getArgs 
  newSocket <- socket AF_INET Stream defaultProtocol 
  setSocketOption newSocket ReuseAddr 1
  bindSocket newSocket $ SockAddrInet port iNADDR_ANY
  listen newSocket 2
  runServer echo newSocket

runServer :: (String -> String) -> Socket -> IO()
runServer f s = forever $ do
  (usableSocket,_) <- accept s
  forkIO $ interactWithSocket f usableSocket 

interactWithSocket :: (String -> String) -> Socket -> IO()
interactWithSocket f s = do 
  handle <- socketToHandle s ReadWriteMode
  forever $ f <$> recv handle 1024 >>= process >> putStrLn (prettyPrint msg)

process :: ByteString -> IO ()
process input = let command = B.take 2 $ B.take 2 input in
                  putStrLn (prettyPrint)

我得到输出:

0x1 0x11 0x80 0x5 0x0 0x0 0x0 0x0
0x80 0x5

按预期运行

uspip  --tcp-port 1024 list -r localhost
后。 但是当我用

替换主要功能时
main = putStrLn $ prettyPrint $ toStrict (toByteString (BO.toBigEndian (fromInteger 0x8005) :: Word16))

我得到输出:

0x31 0x34 0x30 0x38

注意我正在尝试编写一个 https://docs.kernel.org/usb/usbip_protocol.html 服务器。

因此,我需要能够将命令代码(例如 0x8005)存储在常量中,以便了解正在接收哪些命令。

haskell
1个回答
0
投票

问题是您正在使用

toByteString
...这是一台漂亮的打印机,因此您正在检查漂亮的打印输出(请参阅实现)。

您可以首先构建正确的字节串,而不是尝试构建整数并尝试转换字节串:

B.pack [0x80, 0x05]
© www.soinside.com 2019 - 2024. All rights reserved.