gpt4 book ai didi

macos - 在 OSX 上设置套接字选项

转载 作者:行者123 更新时间:2023-12-04 04:35:35 27 4
gpt4 key购买 nike

我正在尝试在使用 Network.Socket 构造的套接字上设置接收超时。模块。这是一个代码片段:

import Network.Socket

host = "127.0.0.1"
port = PortNumber 3000

main = do
addrinfos <- getAddrInfo Nothing (Just host) (Just port)
let serveraddr = head addrinfos
sock <- socket (addrFamily serveraddr) Stream defaultProtocol
setSocketOption sock RecvTimeOut 120000000
connect sock (addrAddress serveraddr)
msg <- recv sock 1024
putStrLn msg
sClose sock
setSocketOption行抛出异常:
*** Exception: setSocketOption: invalid argument (Invalid argument)
setSocketOption只接受 Int设置参数,但并非所有套接字选项都需要 Int .具体 RecvTimeOutSendTimeOut期待 struct timeval .还有另一种方法可以从haskell设置这些选项吗?

我在 OSX 10.8.1 上运行 GHC 7.4.2

编辑:
Network.Socket.Options似乎是这里最好的解决方案,并且让它在 OSX 上编译结果只需要一个很小的拉取请求。从 0.2.0.1 版开始, network-socket-options现在在 OSX 上编译。

编辑 2: Network.Socket.Options 运气不好. setRecvTimeout功能似乎对 OSX 没有任何影响。我最终使用了 timeout来自 System.Timeout包作为解决方法。
msg <- timeout 120000000 $ recv sock 1024

最佳答案

我从这里阅读了有关 Haskell 和结构定义的信息:http://therning.org/magnus/archives/315
.来自 MSDN 的 struct timeval 定义在这里(它在 GNU 和可能在 OSX 上是相同的结构):http://msdn.microsoft.com/en-us/library/windows/desktop/ms740560(v=vs.85).aspx

时间 C header :

...
typedef struct timeval {
long tv_sec;
long tv_usec;
} timeval;
....

似乎您需要在 Haskell 中定义某种结构构造函数。或者像这样完全绑定(bind)到时间 header (取自 http://hackage.haskell.org/packages/archive/bindings-common/0.1.4/doc/html/src/CTypes.html):
                module CTypes where
import Foreign
import Foreign.C

-- time.h

data Tm = Tm {
tm'sec,
tm'min,
tm'hour,
tm'mday,
tm'mon,
tm'year,
tm'wday,
tm'yday,
tm'isdst :: CInt
}

instance Storable Tm where
sizeOf _ = fromIntegral size_of_tm
alignment = sizeOf
peek p =
with 0 $ \p1 -> with 0 $ \p2 -> with 0 $ \p3 ->
with 0 $ \p4 -> with 0 $ \p5 -> with 0 $ \p6 ->
with 0 $ \p7 -> with 0 $ \p8 -> with 0 $ \p9 ->
c2hs_tm p p1 p2 p3 p4 p5 p6 p7 p8 p9 >>
peek p1 >>= \v1 -> peek p2 >>= \v2 -> peek p3 >>= \v3 ->
peek p4 >>= \v4 -> peek p5 >>= \v5 -> peek p6 >>= \v6 ->
peek p7 >>= \v7 -> peek p8 >>= \v8 -> peek p9 >>= \v9 ->
return $ Tm v1 v2 v3 v4 v5 v6 v7 v8 v9
poke p (Tm v1 v2 v3 v4 v5 v6 v7 v8 v9) =
hs2c_tm p v1 v2 v3 v4 v5 v6 v7 v8 v9

foreign import ccall size_of_tm :: CInt

foreign import ccall hs2c_tm
:: Ptr Tm -> CInt -> CInt -> CInt -> CInt ->
CInt -> CInt -> CInt -> CInt -> CInt -> IO ()

foreign import ccall c2hs_tm
:: Ptr Tm -> Ptr CInt -> Ptr CInt -> Ptr CInt -> Ptr CInt ->
Ptr CInt -> Ptr CInt -> Ptr CInt -> Ptr CInt ->
Ptr CInt -> IO ()

-- sys/time.h

data Timeval = Timeval {timeval'tv_sec, timeval'tv_usec :: CLong}

instance Storable Timeval where

sizeOf _ = fromIntegral size_of_timeval

alignment = sizeOf

peek p =
with 0 $ \p1 ->
with 0 $ \p2 ->

c2hs_timeval p p1 p2 >>

peek p1 >>= \v1 ->
peek p2 >>= \v2 ->

return $ Timeval {timeval'tv_sec = v1, timeval'tv_usec = v2}

poke p v = hs2c_timeval p (timeval'tv_sec v) (timeval'tv_usec v)

foreign import ccall "size_of_timeval" size_of_timeval
:: CInt

foreign import ccall "hs2c_timeval" hs2c_timeval
:: Ptr Timeval -> CLong -> CLong -> IO ()

foreign import ccall "c2hs_timeval" c2hs_timeval
:: Ptr Timeval -> Ptr CLong -> Ptr CLong -> IO ()

精简为必要的版本将是:
module CTypes where
import Foreign
import Foreign.C

-- sys/time.h

data Timeval = Timeval {timeval'tv_sec, timeval'tv_usec :: CLong}

然后,您应该能够通过以下方式初始化 timeval 结构:
timeval <- Timeval { tv_sec=120 , tv_usec=0 }

我希望这会有所帮助...

关于macos - 在 OSX 上设置套接字选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12590202/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com