babyAの日記: recvfromではまりまくり
たとえばUDPソケットを使う簡単なサーバ
--
require 'socket'
require 'thread'
q = Queue.new
sk = UDPSocket.open
sk.bind("", 30905)
#受信スレッド
r = Thread.start {
loop {
dat, addr = sk.recvfrom(0xffff)
p v = [dat, addr[2], addr[1]]
q.push v
}
}
#送信スレッド
s = Thread.start {
loop {
dat, host, port = q.shift
sk.send(dat, 0, host, port)
}
}
loop{ sleep(1) }
--
にクライアントから送信していると受信スレッドの
recvfromが先に進まなくなることがある。
Linux上では問題なし。
windows(cygwin版,mswin32版)だとうまくいかない。
調べてみると送信スレッドがsendするときに
クライアント側ソケットが既にない場合に必ず起きる。
Thread.abort_on_exception = true
でやってみたらrecvfromが例外を起こして受信スレッドが
死んでいることが判明。
windowsでは送信先にソケットが無いとこへsendすると
ICMPを受けてrecvfromが例外発生するのかな?(よくわかんないけど)
とりあえず
begin
dat, addr = sk.recvfrom(0xffff)
rescue Exception
retry
end
で例外を補足してやればうまくいく。
例外のtypeはruby1.6.8(cygwin),ruby1.8(mswin32)で
違うからExceptionで補足するのがよさげだ。
recvfromではまりまくり More ログイン