有没有办法将IO句柄转换为套接字?

时间:2014-07-25 03:14:41

标签: haskell networking

我正在搞乱Haskell中的网络,需要修改connectTo在超时之前尝试连接的时间。不幸的是,connectTo返回一个句柄,它没有任何可修改的超时参数。有没有人知道从connectTo返回的句柄获取Socket的任何方法? (或者只知道使用句柄来修改超时的任何方法)

谢谢

1 个答案:

答案 0 :(得分:2)

套接字操作的级别低于Handle。通过查看network包的来源,我能够提出以下使用句柄修改超时的方法:

import qualified Control.Exception as Exception
import           Data.Int (Int64)
import           Network
import           Network.BSD
import qualified Network.Socket as Socket (accept)
import           Network.Socket hiding (accept, socketPort, recvFrom, sendTo, PortNumber, sClose)
import           Network.Socket.Options (setSendTimeout)
import           System.IO

type MicroSeconds = Int64

myconnectTo :: HostName           -- Hostname
          -> PortID             -- Port Identifier
          -> MicroSeconds
          -> IO Handle          -- Connected Socket

myconnectTo hostname (Service serv) t = do
    proto <- getProtocolNumber "tcp"
    bracketOnError
        (socket AF_INET Stream proto >>= \x
         -> setSendTimeout x t >> return x)
        (sClose)  -- only done if there's an error
        (\sock -> do
          port  <- getServicePortNumber serv
          he    <- getHostByName hostname
          connect sock (SockAddrInet port (hostAddress he))
          socketToHandle sock ReadWriteMode
        )

myconnectTo hostname (PortNumber port) t = do
    proto <- getProtocolNumber "tcp"
    bracketOnError
        (socket AF_INET Stream proto >>= \x
         -> setSendTimeout x t >> return x)
        (sClose)  -- only done if there's an error
        (\sock -> do
          he <- getHostByName hostname
          connect sock (SockAddrInet port (hostAddress he))
          socketToHandle sock ReadWriteMode
        )

bracketOnError = Exception.bracketOnError

请注意,我实际上并没有测试过这些代码,但它确实存在问题。应该注意的是,它只适用于IPv4系统,但很容易适应network包中的IPv6。我正在使用network-options包中的setSendTimeout函数来操作超时。