2014-07-25 3 views
2

나는 Haskell의 Networking을 망설이고 있으며, connectTo가 얼마나 오래 타임 아웃하기 전에 연결을 시도 할 것인지를 수정할 필요가있다. 불행하게도, connectTo는 수정 가능한 타임 아웃 매개 변수가없는 핸들을 반환합니다. 누구든지 소켓에서 connectTo에 의해 반환 된 핸들을 얻는 방법을 알고 있습니까?IO 핸들을 소켓으로 변환하는 방법이 있습니까?

(또는 만 핸들을 사용하여 타임 아웃을 수정하는 어떤 방법 알고)는

+0

'System.Timeout.timeout'을 사용해 보셨습니까? 그 정도면 충분할 것입니다. [일반적인 방법으로 Handle을 Socket으로 변환하는 방법은 없다고 생각합니다. (https://www.haskell.org/hoogle/?hoogle=Handle+-%3E+IO+Socket) OS 관점에서 상당히 다른 실체입니다. – bheklilr

+0

실제로 connectTo (시간 초과되기 전에 시간 줄이기) 동작을 변경하고 결과 핸들을 변경하지 않으므로 내 질문에 답할 수 없다는 사실을 알았습니다. 질문을 삭제 하겠지만 담당자 변경은 원하지 않습니다. 그리고 당신이 언급 한 모듈이 타임 아웃을 추가하지 않습니까? 현재 시간 초과를 ~ 10 초에서 1 (또는 그 이하)로 줄이려고합니다. – Carcigenicate

답변

2

소켓 핸들보다 낮은 수준에서 작동 감사드립니다. 실제로 코드를 테스트하지 않았습니다

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 

참고하지만 typechecks 다음 network 패키지의 소스보고, 나는 핸들을 사용하여 타임 아웃을 수정하는 다음과 같은 방법을 마련 할 수 있었다. IPv4 시스템에서만 작동하지만 IPv6에 대해서는 network 패키지에서 쉽게 적용 할 수 있습니다. 나는 network-options 패키지의 setSendTimeout 기능을 사용하여 타임 아웃을 조작하고 있습니다.

+0

당신은 신이 십니다. 고맙습니다. – Carcigenicate

관련 문제