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
私は上記の呼び出しが非常に長い(または非常に少なくともためにブロックされないようにします無期限にブロックされません)。しかし、私のUNIXソケットの理解はそれほど深くはなく、正確に理解するのが難しいです。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
の自分のフォークを作る必要がありますか、何か不足していますか?
私はここではLinuxに関心があります。
EDIT:また、どのようなおそらく私はこのすべてを始めましたが、私はメトリックコレクタが実行されていないとき、私の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"
:ここでは誰もがREPROを手助けしたい場合は、接続を拒否した問題を説明するための完全な例です。
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'ソケットは送信をブロックしません。ネットワーク上にパケットをダンプするだけです。受信側のバッファがいっぱいになると、パケットは破棄されます。接続がないので、ブロックすることはありません。 –