大家好,首次发帖呀。最近在苦修 Ruby,刚好需要记录好几台机器的内存信息,就写了个 socket 程序,基本功能是实现了,但是还是有点问题想破脑壳……智商不够用啊……程序是这样的: 首先开始服务端 server,然后开启客户端 client,建立连接之后 server 发送 start,每台机器的 client 开始发送信息到 server。最后记录完毕,server 发送 stop 关闭 socket。
server:
require 'socket'
# This method expects a socket connected to a client.
# It reads the logs from the client and control the client(start or stop).
# Multiple threads may run this method at the same time.
def handle_client(c, cmd)
command = cmd
# Connection feekback
c.puts "Log service running on #{Socket.gethostname}"
c.flush
puts "Accepted connection from #{c.peeraddr[2]}"
c.puts command
while true
remsg = c.gets.chop
puts "#{c.peeraddr[2]}: #{remsg}" # Main work
c.puts command # Control the client
c.flush
break if command == "stop"
end
c.close
end
server = TCPServer.open(2000)
cmd = ""
# Wait for the command
cmdThread = Thread.new do
loop do
cmd = STDIN.gets.chop
if cmd == "stop"
break
elsif cmd == "start"
STDOUT.puts "Log service start!"
else
STDOUT.puts "Unreasonable command!"
end
end
end
while true
if cmd == "start" || cmd == "stop"
client = server.accept
puts "Client connected. CMD: #{cmd}."
Thread.start(client) do |c|
handle_client(c, cmd)
end
end
end
client:
require 'socket'
host, port = ARGV
interval = 1
begin
# Give the user some feedback while connecting.
STDOUT.print "Connecting..."
STDOUT.flush
s = TCPSocket.open(host, port)
STDOUT.puts "done"
# Now display information about the connection
local, peer = s.addr, s.peeraddr
STDOUT.print "Connected to #{peer[2]}:#{peer[1]}"
STDOUT.puts " using local port #{local[1]}"
msg = s.gets
STDOUT.puts msg.chop # And display it
# Waiting the "start" command from server.
loop do
STDOUT.puts "Waiting the commands from server."
msg = s.gets.chop
STDOUT.puts "Server Command: #{msg}."
if msg == "start"
break
else
STDOUT.puts "Unreasonable commands!"
end
end
# Now begin a loop of client/server interaction.
loop do
STDOUT.print '> '
STDOUT.flush
meminfo = `free`.split "\n"
memused = meminfo[2].split[2].to_f
memtotal = meminfo[1].split[1].to_f
memcost = (memused / memtotal).round(4)
STDOUT.puts "#{Time.new} MemCost: #{memcost}"
s.puts(memcost) # Send the logs to the server
s.flush
# Read the server's response and print out.
# The server may send more than one line, so use readpartial
# to read whatever it sends (as long as it all arrives in one chunk).
response = s.readpartial(4096)
break if response.chop == "stop"
sleep(interval)
end
rescue # If anything goes wrong
puts $! # Display the exception to the user
ensure
s.close if s
end
现在的问题是,server 发送 start 没问题,可是发送不了 stop……求大牛拯救!