作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我用Ruby编写了小UDP服务器:
def listen
puts "Started UDP server on #{@port}..."
Socket.udp_server_loop(@port) do |message, message_source|
puts "Got \"#{message}\" from #{message_source}"
handle_incoming_message(message)
end
end
thread = Thread.new { listen }
udp_server_loop
而不只是杀死它(
thread.kill
)?我也不想通过接收任何UDP消息从内部停止它。
udp_server_loop
可能不是适合我的工具吗?
最佳答案
我认为您无法使用udp_server_loop
做到这一点(尽管您也许可以使用它使用的某些方法)。您将不得不在自己的循环中调用 IO::select
,并用某种信号通知它退出,并通过某种方式唤醒线程,这样就不必发送数据包来停止它了。
一种简单的方法是使用select
的timeout选项和一个变量来设置,以指示您希望线程结束,例如:
@halt_loop = false
def listen
puts "Started UDP server on #{@port}..."
sockets = Socket.udp_server_sockets(@port)
loop do
readable, _, _ = IO.select(sockets, nil, nil, 1) # timeout 1 sec
break if @halt_loop
next unless readable # select returns nil on timeout
Socket.udp_server_recv(readable) do |message, message_source|
puts "Got \"#{message}\" from #{message_source}"
handle_incoming_message(message)
end
end
end
@halt_loop
设置为true。
pipe
并使select与套接字一起监听。然后,您可以直接发出信号以完成
select
并退出线程。
@read, @write = IO.pipe
@halt_loop = false
def listen
puts "Started UDP server on #{@port}..."
sockets = Socket.udp_server_sockets(@port)
sockets << @read
loop do
readable, _, _ = IO.select(sockets)
break if @halt_loop
readable.delete @read
Socket.udp_server_recv(readable) do |message, message_source|
puts "Got \"#{message}\" from #{message_source}"
handle_incoming_message(message)
end
end
end
def end_loop
@halt_loop = true
@write.puts "STOP!"
end
end_loop
即可,该命令会设置
@halt_loop
标志,然后将其写入管道,使另一端可读,并使另一个线程从
select
返回。
IO
,如果其中之一是管道的读取端而不是使用变量,则退出,但至少在Linux上存在潜在的错误,其中select调用可能返回文件描述符为实际不可读时可读。我不知道Ruby是否可以解决这个问题,所以安全胜过遗憾。
readable
之前,请确保从
udp_server_recv
数组中删除管道。它不是套接字,如果不这样做,将导致异常。
关于ruby - 如何从外部停止udp_server_loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57575662/
我是一名优秀的程序员,十分优秀!