다른 데몬이 이러한 메시지를 수신하고 집계/프록시하는 SOCK_DGRAM
에 메트릭을 보낼 수있는 코드가 있습니다. 소켓을 열면 다음과 같습니다무한대로 차단하지 않고 데이터 그램 소켓으로 보내기
sock <- socket
(ai :: AddressInfo Inet Datagram UDP):_ <- getAddressInfo (Just "127.0.0.1") Nothing aiNumericHost
connect s (socketAddress ai) { port }
return sock
우리가 쓸 순간에 좋아 :
send sock payload mempty
을 나는 위의 적어도 (또는 아주 오랫동안 차단하지 않습니다 전화를 확인하려면 무한히 차단하지는 않습니다.)하지만 유닉스 소켓에 대한 이해는 그리 깊이가 없으며 정확히 send
블록을 이해하고, 내부를 보면서 문제가 발생했습니다. here 및 here.
도움이되었다 여기에 관련된 질문이있다 : When a non-blocking send() only transfers partial data, can we assume it would return EWOULDBLOCK the next call?
그래서 제 질문은 구체적으로 다음과 같습니다
- 일반 소켓 질문 :
send
차단할 것입니다이 구현에서 볼 (바쁜 대기 후) 버퍼에 공간이있을 때까지. 이 버퍼가 소비자와 얼마나 관련이 있습니까?listen
ing 데몬이 느리거나 멈 추면send
이 무기한 차단 될 수 있습니까? - 내가 중단하고 결코 차단하지 않으려면
System.Socket.Unsafe
의 자체 포크를 만들어야합니까, 아니면 뭔가 빠졌습니까?
저는 여기서 리눅스에만 관심이 있습니다.
편집 : 또한, 어떤 아마 내가이 모든 시작있어 내가 메트릭 콜렉터가 실행되지 않을 때, 내 send
전화의 다른 모든 위에서 발생하는 예외를 "연결이 거부"찾을 수 있습니다. 그렇다면 왜 그런가, 아니면 정상인지 여부에 대한 또 다른 질문이 있습니다.
EDIT2
: 나는이socket-0.5.3.0
을 사용하고
import Data.Functor
import System.Socket
import System.Socket.Family.Inet
repro :: IO()
repro = do
let port = 6565
(s :: Socket Inet Datagram UDP) <- socket
(ai :: AddressInfo Inet Datagram UDP):_ <- getAddressInfo (Just "127.0.0.1") Nothing aiNumericHost
connect s (socketAddress ai) { port }
putStrLn "Starting send"
void $ send s "FOO" mempty
void $ send s "BAR" mempty
putStrLn "done"
: 여기 사람이 생식 도움을 좋아하면 연결 거부 문제를 보여주는 완벽한 예입니다.
EDIT3 : 이것은 다소 connect
호출로 인한 것 같습니다. (시험에 대한 최신 sockets
) : 내가 알고있는 것처럼
{-# LANGUAGE ScopedTypeVariables, OverloadedStrings, NamedFieldPuns #-}
import Data.Functor
import System.Socket
import System.Socket.Protocol.UDP
import System.Socket.Type.Datagram
import System.Socket.Family.Inet
repro :: IO()
repro = do
(s :: Socket Inet Datagram UDP) <- socket
-- Uncommenting raises eConnectionRefused, everytime:
-- connect s (SocketAddressInet inetLoopback 6565 :: SocketAddress Inet)
putStrLn "Starting send"
void $ sendTo s "FOO" mempty (SocketAddressInet inetLoopback 6565 :: SocketAddress Inet)
void $ sendTo s "BAR" mempty (SocketAddressInet inetLoopback 6565 :: SocketAddress Inet)
putStrLn "done"
우리는 기본 주소를 보내 설정 connect
(적어도 기본 콜)를 사용할 수 있어야합니다. 아직 도서관에 connect
의 구현을 파헤 치지 않았습니다.
나는 이것을 연 : https://github.com/lpeterse/haskell-socket/issues/55
STREAM 및 DGRAM 소켓은 매우 다르게 작동합니다. DGRAM 소켓은 실제로 상대방에서 듣고있는 것이 있는지를 모르고도 신경 쓰지 않습니다. 성간 공간으로 전달하는 모든 것을 발사합니다. –
'send '에 대한'MSG_DONTWAIT' 플래그가 적절할 것 같습니다. Haskell 인터페이스는 플래그를 통과시키고 어딘가에 상수를 정의합니다. 그러나 이러한 것들에 대한 나의 이해는 아마도 당신보다 더 얕습니다. – dfeuer
'DGRAM' 소켓은 송신을 차단하지 않습니다. 단지 패킷을 네트워크에 덤프하고 수신기의 버퍼가 가득 차면 패킷을 버립니다. 연결이 없으므로 차단할 수 없습니다. –